Categories: C++

Virtual Destructors in C++

What is a Virtual Destructor?
  • Deleting a derived class object with a non-virtual destructor using a pointer of the base class type results in undefined behavior.
  • While deleting instances of the derived class using a base class pointer object, a virtual destructor is used to free up the memory space allocated by the derived class object or instance.
  • A virtual keyword is used in a base or parent class destructor to ensure that both the base class and the derived class destructors are called at run time, but it calls the derived class first and then the base class to free up the space occupied by both destructors.
  • NOTE: Constructors can never be Virtual; only Destructors can.
Example: Without virtual destructor

The following program results in undefined behavior.


#include <iostream>

using namespace std;

class A {
public:
 A() 
 { 
     cout << "Constructing A\n"; 
     
 }
 ~A()
 {
     cout<< "Destructing A\n";
     } 
};

class B: public A {
public:
 B() 
 {
     cout << "Constructing B\n"; 
     
 }
 ~B()
 {
     cout << "Destructing B\n"; 
     
 }
};

int main()
{
B *d = new B();
A *b = d;
delete b;
getchar();
return 0;
}
Output:
Constructing A
Constructing B
Destructing A
Example: With virtual destructor

Making the base class destructor virtual ensures that the object of the derived class is properly destructed, i.e., both the base class and the derived class destructors are called.


#include <iostream>

using namespace std;

class A {
public:
 A() 
 { 
     cout << "Constructing A\n"; 
     
 }
   virtual ~A()
 {
     cout<< "Destructing A\n";
     } 
};

class B: public A {
public:
 B() 
 {
     cout << "Constructing B\n"; 
     
 }
 virtual ~B()
 {
     cout << "Destructing B\n"; 
     
 }
};

int main()
{
B *d = new B();
A *b = d;
delete b;
getchar();
return 0;
}
Output:
Constructing A
Constructing B
Destructing B
Destructing A
Pure Virtual Destructors:
  • In C++, a pure virtual destructor can be declared.
  • After a destructor is created as a pure virtual object (class instance), the destructor body is provided.
  • This is because destructors are not overridden in derived classes, but are instead called in reverse order. As a result, one must specify a destructor body for a pure virtual destructor.
Example:

#include <iostream>
using namespace std;

class A {
public:
 virtual ~A() = 0;
 // Pure virtual destructor

};
 A::~A() // Explicit destructor call
{
    std::cout << "Pure virtual destructor is called";
}

class B : public A {
public:
 ~B() { cout << "~B() is executed"; }
};

int main()
{
 A* b = new B();
 delete b;
 return 0;
}
Output:
~B() is executed
Pure virtual destructor is called

Note: also read about Pure Virtual Functions and Abstract Classes

Follow Me

Please follow me to read my latest post on programming and technology if you like my post.

https://www.instagram.com/coderz.py/

https://www.facebook.com/coderz.py

Recent Posts

Generate Parenthesis | Intuition + Code | Recursion Tree | Backtracking | Java

Problem Statement: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses. Example…

3 months ago

Square Root of Integer

Given an integer A. Compute and return the square root of A. If A is…

1 year ago

Build Array From Permutation

Given a zero-based permutation nums (0-indexed), build an array ans of the same length where…

1 year ago

DSA: Heap

A heap is a specialized tree-based data structure that satisfies the heap property. It is…

2 years ago

DSA: Trie

What is a Trie in DSA? A trie, often known as a prefix tree, is…

2 years ago

Trees: Lowest Common Ancestor

What is the Lowest Common Ancestor? In a tree, the lowest common ancestor (LCA) of…

2 years ago