class Base // Base Class
{
public:
~Base () {} // Destructor for Base()
};
class Derived : public Base // Derived Class
{
public:
~Derived () {} // Destructor for Derived()
};
Base *obj = new Derived(); // Create Base pointer that points to Derived
// Things go wrong here!
delete obj;
When obj
is being deleted, the destructor for Base
will be invoked. This is dangerous because it leaks memory → Derived
’s destructor is not called, hence the contents of the Derived
class will remain dangling
Virtual destructors make sure that the right destructors are invoked in an intuitive manner
class Base // Base Class
{
public:
virtual ~Base () {} // Destructor for Base()
};
class Derived : public Base // Derived Class
{
public:
~Derived () {} // Destructor for Derived()
};
Base *obj = new Derived(); // Create Base pointer that points to Derived
// All good!
delete obj;
Here, when obj
is being deleted, the destructor of Derived
will first be called and then Base
’s destructor is called, thus ensuring no memory leaks and a safe cleanup.