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.
class 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;
}