Virtual destructors

Virtual destructor in base class ensures that the destructor of derived class will be called when using base pointer to the object.

Destructors in inheritance

Suppose we have a base class and a derived class. Both base and derived class have normal constructors and destructors. We are allocating some buffer for the member variable "name". We are also deleting this buffer at the time of destruction.

class base 
{
  public: base()
  {
    cout << "base construction";
  }
  ~base()
  {
    cout << "base destruction";
  }
};
class derived : public base
{
  char *name;
  public : derived ()
  {
    cout << "derived construction";
    name = new char[10];
    cout << "mem allocated for name";

  }
  ~ derived ()
  {
    cout << "derived destruction";
    delete [] name;
    cout << "mem de-allocated for name";
  }
};
int main (int argc, char *argv[])
{
  base *= new derived();
  delete b;
}

Destructor sequence in inheritance

This is how the constructors and destructors are getting called.

base construction
derived construction
mem allocated for name
base destruction

Here derived destruction is missing. Thus derived destructor is not getting called by compiler as it is early/compile time bind. As the type of the object is base, only base destructor is getting called.

Destructor sequence and memory leak

We generally allocate dynamic memory buffers in constructors and the same memory should be deallocated in destructor. This type of destructors are never called by compiler. As a result of this, dynamic memory units are never deallocated. This leads to a situation known as memory leaks. Memory leak can slow down an application and even can slow down operating system.

Virtual destructor in base class

To ensure proper destructor sequence call we must make the base destructor virtual. This ensures dynamic/runtime binding of the destructor through vtable mechanism After modifying the prototype ~base() to virtual ~base() the sequence will be as expected as below.

class base 
{
  public: base()
  {
    cout << "base construction";
  }
  virtual ~base() 
  {
    cout << "base destruction";
  }
};

Virtual destructor sequence

Output after this change:
base construction
derived construction
mem allocated for name
derived destruction
mem de-allocated for name
base destruction

Virtual destructor sequence diagram

Virtual destructor sequence diagram

Virtual destructor & inheritance

Similarly in future if we need to inherit child_derived from derived, we must make the destructor i.e. ~derived() as virtual. Thus it is a good practice to make destructor always virtual. This ensures proper calling sequence of destructors as it gets inherited down in the child classes.

A good C++ editor always takes care of this. VC++ editor always makes destructor as virtual when it is created using wizard or template.

About our authors: Team EQA

You have viewed 1 page out of 62. Your C++ learning is 0.00% complete. Login to check your learning progress.

#