Calling the destructor of a derived class in an inheritance hierarchy should invoke the destructors that class and all of its base classes. However, if the derived class is referenced by a pointer of a type higher up the class hierarchy, then the destructor of the pointer's type will be called rather than the destructor of the class being pointing to. As a result the derived class's destructor will not be called leading to resource mismanagement and possibly unintended program behavior.
Non-Compliant Code Example
In this non-compliant example, a reference to the parent class Base
is used to instantiate a Derived
object. When b
is deleted, the destructor for Base
is invoked rather than the destructor for Derived
. As a result, the object b
refers to will be improperly destroyed.
class Base { public: Base() { // Build Base object } ~Base() { // Destroy Base object } }; class Derived : public Base { public: Derived() { // Build Derived object } ~Derived() { // Destroy Derived object } }; void function(void) { Base* b = new Derived(); // ... delete b; }
Compliant Solution
To correct this example, the destructor for Base
should be declared virtual
. This ensures that the object b
refers to will be correctly evaluated at runtime thus, deleting b
will call the destructor for class Derived
.
cclass Base { public: Base() { // Build Base object } virtual ~Base() { // Destroy Base object } }; class Derived : public Base { public: Derived() { // Build Derived object } ~Derived() { // Destroy Derived object } }; void function(void) { Base* b = new Derived(); // ... delete b; }