Virtual Destructors in C++

  • We cannot use the virtual keyword with constructors, but destructors can and often must be virtual.
  • The constructor has the special job of putting an object together piece by piece, first by calling the base class constructor, then the more derived class constructors in order of inheritance. Similarly, the destructor has a special job: it must disassemble an object that may belong to a hierarchy of classes.
  • To do this, the compiler generates code that calls all the destructors, but in the reverse order that they are called by the constructor. That is, the destructor starts at the most derived class and works its way down to the base class.
  • This is the safe and desirable thing to do because the current destructor can always know that the base class members are alive and active.
  • Each destructor knows what its class is derived from, but not what is derived from it.
  • The problem occurs when you want to delete a pointer of this type for an object that has been created on the heap with new keyword.
  • If the pointer is to the base class, the compiler can only know to call the base class version of the destructor during delete.

#include <iostream>

using namespace std;

#include<stdio.h>

class Base1

{

public:

Base1()

{

printf(“Base1()\n”);

}

~Base1()

{

printf(“~Base1()\n”);

}};

class Derived1 : public Base1

{

public:

Derived1()

{

printf(“Derived1()\n”);

}

~Derived1()

{

printf(“~Derived1()\n”);

}};

class Base2

{

public:

Base2()

{

printf(“Base2()\n”);

}

virtual ~Base2()

{

printf(“~Base2()\n”);

}};

class Derived2 : public Base2

{

public:

Derived2()

{

printf(“Derived2()\n”);

}

~Derived2()

{

printf(“~Derived2()\n”);

}};

int main()

{

Base1* bp = new Derived1; // Upcast

delete bp;

Base2* b2p = new Derived2; // Upcast

delete b2p;

}

Output:-

Base1()

Derived1()

~Base1()

Base2()

Derived2()

~Derived2()

~Base2()

  • delete bp only calls the base class destructor, while delete b2p calls the derived class destructor followed by the base class destructor, which is the behavior we desire.
  • Forgetting to make a destructor virtual is a bug because it often does not directly affect the behavior of your program, but it can quietly introduce a memory leak.
  • While pure virtual destructors are legal in Standard C++, there is an added constraint when using them: you must provide a function body for the pure virtual destructor.
  • The only difference you will see between the pure and non pure virtual destructor is that the pure virtual destructor does cause the base class to be abstract, so you cannot create an object of the base Unlike every other pure virtual function, you are not required to provide a definition of a pure virtual destructor in the derived class.
  • Like a normal abstract class we are unable to create the object of the class which contains pure virtual destructor.

class AbstractBase

{

public:

virtual ~AbstractBase() = 0;

};

AbstractBase::~AbstractBase()

{

}

class Derived : public AbstractBase

{

};

// No overriding of destructor necessary

int main()

{

Derived d;

}

Sourabh Bhunje

Sourabh Bhunje, B.E. IT from Pune University. Currently Working at Techliebe. Professional Skills: Programming - Software & Mobile, Web & Graphic Design, Localization, Content Writing, Sub-Titling etc. http://techliebe.com/about-us

Leave a Reply