class Base {
public:
virtual ~Base () { cout << "Base Dtor" << endl; }
virtual void doSomething () { cout << "Base do something" << endl; }
};
class Derive : public Base {
public:
~Derive () { cout << "Derive Dtor" << endl; }
void doSomething () { cout << "Derive do something" << endl; }
};
when I try to write some code like:
Base* ptr = new Derive;
ptr->doSomething ();
delete ptr;
the function doSomething()
is called correctly. Why the derived destructor is called and then base destructor is called? But doSomething()
just only call the derived class's version. Destructor and doSomething()
are also function but why do they behave differently?
Object destructors are special. Yes, they are functions, but they actually represent something particular. Namely, destroying an object.
In your example Derive
is an object. But through inheritance, Derive
has a base class subobject called Base
. That is, for every Derive
, there is also a Base
living within that Derive
object.
When you invoke a constructor to create a Derive
, the appropriate constructor will be invoked for the Base
subobject as well (depending on how you defined your Derive
constructor). As such, if you destroy a Derive
, the Base
living inside of it must also be destroyed.
The virtual
call to the destructor doesn't actually change this. What it being virtual
does is allow the system to start the chain of destructors correctly. If you had not declared the Base
destructor to be virtual
, then invoking delete
on a base class pointer would only invoke ~Base
. It wouldn't be able to jump up the inheritance graph to call ~Derive
; the delete
expression is given a Base
pointer to delete, so that's what it does.
This is the same mechanism as any virtual
call. If you didn't make a regular member function virtual
, and you call it on a Base
class pointer, then you get the Base
version of it, even if there is a Derive
version with the same name. You need virtual
to make the compiler jump up the inheritance graph and find the right function to call.
But once the compiler knows the right object type to start the chain of destructors, that chain of object destruction will still happen. Derive
contains a Base
, so for a Derive
to be destroyed, its Base
must also be destroyed.