Open In App

Pure Virtual Destructor in C++

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Share
Report issue
Report

A pure virtual destructor can be declared in C++. After a destructor has been created as a pure virtual object(instance of a class), where the destructor body is provided. This is due to the fact that destructors will not be overridden in derived classes, but will instead be called in reverse order. As a result, for a pure virtual destructor, you must specify a destructor body.

When destroying instances of a derived class using a base class pointer object, a virtual destructor is used to free up memory space allocated by the derived class object or instance. 

Note: Only Destructors can be Virtual. Constructors cannot be declared as virtual, this is because if you try to override a constructor by declaring it in a base/super class and call it in the derived/sub class with same functionalities it will always give an error as overriding means a feature that lets us to use a method from the parent class in the child class which is not possible. 

Can a destructor be pure virtual in C++? 
Yes, it is possible to have a pure virtual destructor. Pure virtual destructors are legal in standard C++ and one of the most important things to remember is that if a class contains a pure virtual destructor, it must provide a function body for the pure virtual destructor. 

Why a pure virtual function requires a function body?

The reason is that destructors (unlike other functions) are not actually ‘overridden’, rather they are always called in the reverse order of the class derivation. This means that a derived class destructor will be invoked first, then the base class destructor will be called. If the definition of the pure virtual destructor is not provided, then what function body will be called during object destruction? Therefore the compiler and linker enforce the existence of a function body for pure virtual destructors. 
 
Example:

CPP




// C++ Program to demonstrate a pure virtual destructor
#include <iostream>
using namespace std;
 
// Initialization of base class
class Base {
public:
    virtual ~Base() = 0;
    // Pure virtual destructor
};
 
// Initialization of derived class
class Derived : public Base {
public:
    ~Derived() { cout << "~Derived() is executed"; }
};
 
// Driver Code
int main()
{
    // base class pointer which is
    // allocating fresh storage
    // for Derived function object's
    Base* b = new Derived();
    delete b;
    return 0;
}


The linker will produce the following error in the above program. 

test.cpp:(.text$_ZN7DerivedD1Ev[__ZN7DerivedD1Ev]+0x4c): 
undefined reference to `Base::~Base()'  error: ld returned 1 exit status

Now if the definition for the pure virtual destructor is provided, then the program compiles & runs fine.

CPP




// C++ program to demonstrate if the value of
// of pure virtual destructor are provided
// then the program compiles & runs fine.
 
#include <iostream>
 
// Initialization of base class
class Base {
public:
    virtual ~Base() = 0; // Pure virtual destructor
};
Base::~Base() // Explicit destructor call
{
    std::cout << "Pure virtual destructor is called";
}
 
// Initialization of derived class
class Derived : public Base {
public:
    ~Derived() { std::cout << "~Derived() is executed\n"; }
};
 
int main()
{
    // Calling of derived member function
    Base* b = new Derived();
    delete b;
    return 0;
}


Output

~Derived() is executed
Pure virtual destructor is called

How did the above code work MAGICALLY?

This basically works because the destructors will be called recursively bottom to up if and only if the value is passed in the virtual destructor. So vtable is a table containing pointers of all virtual functions that the class defines, and the compiler provides vptr to the class as a ‘hidden pointer‘ that points to the ideal vtable, so the compiler makes use of an accurate or correct index, calculated at compile-time, to the vtable which will dispatch the correct virtual function at runtime.

It is important to note that a class becomes an abstract class(at least a function that has no definition) when it contains a pure virtual destructor.

Example:

CPP




// C++ program to demonstrate how a class becomes
// an abstract class when a pure virtual destructor is
// passed
 
#include <iostream>
class Test {
public:
    virtual ~Test() = 0;
    // Test now becomes abstract class
};
Test::~Test() {}
 
// Driver Code
int main()
{
    Test p;
    Test* t1 = new Test;
    return 0;
}


The above program fails in a compilation & shows the following error messages. 

[Error] cannot declare variable 'p' to be of abstract type 'Test' 
[Note] because the following virtual functions are pure within 'Test': 
[Note] virtual Test::~Test() 
[Error] cannot allocate an object of abstract type 'Test' 
[Note] since type 'Test' has pure virtual functions

This article was contributed by Meet Pravasi.



Last Updated : 02 Jun, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads