First off, if you make the base class destructor virtual
, all derived classes will automatically get a virtual
destructor if you declare them as virtual
or not. This is generally true for matching signatures: if a base class has a virtual
function with the same signature as a function in a derived class, the function in the derived class is an override
and is virtual
(although in C++ 2011 you can prevent further overriding using the final
keyword in which case another override would create an error).
That said, destructors are special: when you make a destructor virtual
it will still be called even if there is another overriding destructor! The only impact of a destructor being virtual
is what happens if you delete
an object using a pointer to a base class when the object actually happens to be of a derived type: If the destructor isn't virtual
you get undefined behavior while the Right Thing happens if the destructor is virtual
. For example:
class not_a_base {};
class bad_idea: public not_a_base {};
class a_base { public: virtual ~a_base() {} };
class ok: public a_base {};
int main() {
a_base* ab = new ok;
delete ab; // <---- all is good here!
not_a_base* nab = new bad_idea;
delete nab; // <---- results in undefined behavior
}
The reason destructors are not virtual
by default is simply that this would mean that object size is always increased by a word size which is unacceptable in general.