Virtual destructors

You need a virtual destructor whenever you want to delete a derived class object from a base class pointer. This is because if the base class destructor is non-virtual, the derived class destructor will not be called, as the following code demonstrates:

#include <iostream>

class Base 
{
public:
    ~Base() 
    {
        std::cout << "Base destructor called" << "\n";
    }
};

class Derived : public Base
{
    ~Derived()
    {
        std::cout << "Derived destructor called" << "\n";
    }
};

int main()
{
    Base* b = new Derived();
    delete b;
}

This prints:

Base destructor called

You need to add the virtual keyword to the first line of the destructor definitions as follows:

virtual ~Base()
virtual ~Derived()

And then the output becomes:

Derived destructor called
Base destructor called

This applies even if the derived class does not contain any resources that might be leaked if its destructor is not called, since failure to call a derived class destructor is undefined behaviour.

This means that classes designed to be bases should declare a virtual destructor so that derived classes can override it. It also means that classes that do not have a virtual destructor should not be used as bases, as this means that the class derived from them could not safely be used on a derived class pointer.