Virtual destructors are useful when you can manipulate an instance of a derived class through a pointer to base class:
class Base
{
// some virtual methods
};
class Derived : public Base
{
~Derived()
{
// Do some important cleanup
}
}
Here, you'll notice that I didn't declare Base's destructor to be virtual. Now, let's have a look at the following snippet:
Base *b = new Derived();
// use b
delete b; // Here's the problem! Since Base's destructor is not virtual,
// it's ~Base that is called and not ~Derived. Therefore, all the important
// cleanup is not performed, which can create several resource leaks
To sum up, always make base classes' destructors virtual when they're meant to be manipulated polymorphically.
If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destuctor protected and nonvirtual; by doing so, the compiler won't let you call delete on a base class pointer.
You can learn more about virtuality and virtual base class destructor in this article from Herb Sutter.