Summary: In this tutorial, we will learn about the significance of virtual destructor in C++ with examples.

Introduction to Virtual Destructor

Virtual Destructor in C++ is used to free up the resources used by the derived class object when it is deleted from the memory.

Its main purpose is to make the base class’s destructor a virtual method so that the derived class destructor could be invoked at the time of the object deletion.

To understand the significance of virtual destructor, consider the following example in C++:

#include <iostream>
using namespace std;
 
class Base{
public:
  Base(){
    cout << "Base Constructor \n";
  }
 
  ~Base(){
    cout << "Base Destructor \n";
  }
  
};
 
class Derived: public Base{
public:
  int *n;
  Derived(){
    cout << "Derived Constructor \n";
    n = new int(10);
  }
 
  void display(){
    cout<< "Value: "<< *n << endl;
  }
 
  ~Derived(){
    cout << "Derived Destructor \n";
  }
};
 
int main() {
 Base *obj = new Derived();  //Derived object with base pointer
 delete(obj);                //Deleting object
 return 0;
}

Output:

Base Constructor
Derived Constructor
Base Destructor

In the above example, we have inherited the Base class in the Derived class and created a derived class object using the base class reference in the main method.

Next, we delete the object to release the memory allocated to it.

Note the output, only the base class destructor is called when we delete the derived class object.

Because the destructor of the derived class was not invoked, the raw integer pointer n has not been deleted from the memory, hence causing a memory leak.

This will result in undefined behavior for long-lasting tasks. To fix this we must mark the base class destructor as virtual, so that the derived class destructor is also invoked and we can explicitly delete the raw pointer.

Here is the program after the correction (i.e. base class’s virtual destructor):

#include <iostream>
using namespace std;
 
class Base{
public:
  Base(){
    cout << "Base Constructor \n";
  }
 
  //virtual destructor
  virtual ~Base(){
    cout << "Base Destructor \n";
  }
  
};
 
class Derived: public Base{
public:
  int *n;
  Derived(){
    cout << "Derived Constructor \n";
    n = new int(10);
  }
 
  void display(){
    cout<< "Value: "<< *n << endl;
  }
 
  ~Derived(){
    cout << "Derived Destructor \n";
    delete(n);           //deleting the memory used by pointer
  }
};
 
int main() 
{
 Base *obj = new Derived();  //Derived object with base pointer
 delete(obj);                //Deleting object
 return 0;
}

Output:

Base Constructor
Derived Constructor
Derived Destructor
Base Destructor

The destructor of both the class (Base and Derived) is called this time.

Conclusion

These are some points one should note about polymorphism and destructors in C++:

  • Derived objects must be destroyed in the correct order and all the destructors should be invoked to release the allocated memory.
  • We must always mark the destructor of the base class as virtual.
  • If the base class destructor is virtual then all derived-class destructors are virtual methods.

In this tutorial, we learned what the virtual destructor is and why we should use virtual destructor in C++.

Leave a Reply