Destructors in the Base class can be Virtual. Whenever Upcasting is done, Destructors of the Base class must be made virtual for proper destrucstion of the object when the program exits.
NOTE: Constructors are never Virtual, only Destructors can be Virtual.
Lets first see what happens when we do not have a virtual Base class destructor.
class Base
{
public:
~Base()
{
cout << "Base Destructor\n";
}
};
class Derived:public Base
{
public:
~Derived()
{
cout<< "Derived Destructor\n";
}
};
int main()
{
Base* b = new Derived; // Upcasting
delete b;
}
Base Destructor
In the above example, delete b
will only call the Base class destructor, which is undesirable because, then the object of Derived class remains undestructed, because its destructor is never called. Which results in memory leak.
Now lets see. what happens when we have Virtual destructor in the base class.
class Base
{
public:
virtual ~Base()
{
cout << "Base Destructor\n";
}
};
class Derived:public Base
{
public:
~Derived()
{
cout<< "Derived Destructor";
}
};
int main()
{
Base* b = new Derived; // Upcasting
delete b;
}
Derived Destructor Base Destructor
When we have Virtual destructor inside the base class, then first Derived class's destructor is called and then Base class's destructor is called, which is the desired behaviour.
class Base
{
public:
virtual ~Base() = 0; // Pure Virtual Destructor
};
// Definition of Pure Virtual Destructor
Base::~Base()
{
cout << "Base Destructor\n";
}
class Derived:public Base
{
public:
~Derived()
{
cout<< "Derived Destructor";
}
};