Deleting an instance of inherited class through a pointer to the base class yields memory leaks if destructor of the base class is not declared as
virtual:
main.cpp:
Output:
main()
Parent::Parent()
Child::Child()
Child::foo()
Windows debugger output:
Detected memory leaks!
Dumping objects ->
{142} normal block at 0x00315588, 40 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
It is not enough just to declare base class as virtual, but we need to provide its definition as well (the one with empty body will suffice), otherwise linker will report error (if derived class' destructor is defined, implicitly or explicitly, as it calls base class destructor):
error LNK2001: unresolved external symbol "public: virtual __thiscall Parent::~Parent(void)" (??1Parent@@UAE@XZ)
Note that if our code didn't call (implicitly or explicitly)
Child's destructor, and so
Parent's one, linker would not complain. But in our case we have construction and destruction of
Child object so
Parent needs to have destructor defined:
Output (memory leaks are not reported anymore):
main()
Parent::Parent()
Child::Child()
Child::foo()
Child::~Child()
Parent::~Parent()
We are able to instantiate
Parent class but if we want to prevent that but with keeping default implementation of
foo(), we can declare its destructor as
pure virtual function. But there is one interesting thing: although it is declared as pure virtual, we still need to provide implementation of destructor, otherwise linker will complain (if derived class' destructor is defined - which calls base class destructor)!
Parent as abstract base class:
Just to make this article complete, it is worth mentioning that if
foo() wasn't declared as
virtual in the base class, we would have needed to cast base class pointer to derived class pointer in order to invoke derived class' version of the function:
Output (no memory leaks):
main()
Parent::Parent()
Child::Child()
Parent::foo()
Child::foo()
Child::~Child()
Parent::~Parent()
Further reading:
(Im)pure Virtual Functions