Tutorial Study Image

C++ Destructors


May 26, 2023, Learn eTutorial
330

In this tutorial, we will learn about the C++ destructor, virtual as well as pure virtual destructors. From this tutorial, you will also get a clear idea about when the destructors are called, and also about their rules and regulations in detail.

Destructors in C++

A member function that deletes an object is referred to as a destructor. The compiler will automatically invoke a destructor whenever an object leaves its scope. Destructors are unique member functions that behave in the exact opposite way to constructors; whereas constructors initialize an object, destructors destroy (or delete) the object.

A destructor is the inverse of constructors and is defined similarly to a constructor. The destructors mainly destroy the class objects. In a class, it can only be defined once, and it must share the same name as the class. It is automatically invoked, just like constructors. But a tilde sign (~) is added just before it.

When an object of a class is destroyed, destructors are typically used to deallocate memory and do other cleanings for the object and the members of the class. When a class object exits its scope or is purposefully eliminated, then the destructor is called.


~className{

    // Some code
};
 
Note: No parameters are allowed in C++ destructors. On top of that, destructors cannot be modified.

Example 1


class X {
public:
  // Constructor for class X
  X();
  // Destructor for class X
  ~X();
};
 
  • A destructor is a member function with the class name and it is prefixed by a ~ (tilde).
  • A destructor has no return type as well as no parameters. You cannot take its address. Const, volatile, const volatile, or static declarations are not permitted for destructors. A destructor may be pure virtual or declared virtual.
  • If a class does not have a user-defined destructor and one is required, the compiler declares one implicitly. This implicitly declared destructor is a public element of its class that is inlined.

Example 2

write a C++ program in order to understand the concept of destructors


#include<iostream>
using namespace std;

class Test
{
public:
  Test()
 {
   cout<<"\n Constructor executed";
 }

 ~Test()
  {
   cout<<"\n Destructor executed";
  }
};
main()
{
 Test t;
 return 0;
}

 

Output:


Constructor executed
Destructor executed

Properties of Destructor In C++

  • When an object is destroyed, the destructor function is automatically called.
  • It can't be made static or const.
  • The destructor has no arguments.
  • It does not even have a void return type.
  • It is impossible for an item from a class with a destructor to join the union.
  • The public part of the class should have a destructor declaration.
  • The address of the destructor is inaccessible to the programmer.

When is the destructor called mainly in C++?

When an object leaves its scope, a destructor function is automatically invoked:

The destructors in C++ are mainly called in the following situations:

  1. When the function is completed.
  2. When the program comes to an end.
  3. End of local variable-containing block.
  4. whenever the delete operator is used.

What distinguishes destructors from a normal member function?

As they don't accept any arguments and return nothing, destructors differ from the normal member functions. Destructor names are preceded by a tilde (~), and they share the same name as their class.

Order of destruction in C++

When an item is removed from the scope or deleted, the following series of events occur to complete its destruction:

  • The destructor for the class is called, and the destructor function's body is put to use.
  • The order in which the destructors for non-static member objects are called is determined by their appearance in the class declaration.
  • The order in which the destructors for non-static member objects are called is determined by their appearance in the class declaration.
  • The order of construction or destruction is unaffected by the optional member initialization list which is used in the construction of the members.
  • Non-virtual base class destructors are called in the opposite order from when they were declared.
  • Virtual base class destructors are called in a reverse manner from when they were declared.

What do you mean by virtual destructors?

Undefined behavior arises when a derived class object with a non-virtual destructor is deleted using a pointer of the base class type. This issue can be resolved by adding a virtual destructor to the base class definition.

The Base class's destructors can be virtual. Every time an upcast is performed, the base class's destructors must be turned virtual to ensure that the object is properly destroyed when the program terminates.

The static cast operation is used to print a void pointer's contents. It changes the pointer's void* type to the appropriate data type for the address the pointer is storing:

Upcasting without a virtual destroyer using a C++ program


#include <iostream>
using namespace std;

// declare a class
class base {

   public:
    // Destructor
    ~base() {
        cout << "The Destructor base." << endl;
    }
};
class derived : publicbase {
    public:
    // Destructor
    ~derived() {
        cout << "The Destructor derived." << endl;
    }
}

int main() {

    base* b = new derived; // Upcasting
    delete b;

    return 0;
}

 

Output:


The Destructor base

Explanation

The delete b command in the above example will only call the destructor of the Base class, which is undesirable since it prevents the object of the Derived class from being destroyed because its destructor is not ever called. It causes a memory leak.

Upcasting with a virtual destroyer using a C++ program


#include <iostream>
using namespace std;

// declare a class
class base {

   public:
    virtual ~base() {
        cout << "The Destructor base." << endl;
    }
};
class derived : publicbase {
    public:
    ~derived() {
        cout << "The Destructor derived." << endl;
    }
}

int main() {

    base* b = new derived; // Upcasting
    delete b;

    return 0;
}

 

Output:


The Destructor base 
The Destructor derived

Explanation: When we have a Virtual destructor inside the base class, the desired behavior is that the Derived class's destructor is called first, followed by the Base class's destructor.

What do you mean by a Pure Virtual Destructor?

When a destructor's starting value is set to 0. It is referred to as a virtual destructor and is stated in the base class. A pure virtual destructor is another option, similar to a virtual destructor. However, it must be declared in the base class.

The primary difference between a Virtual and a Pure Virtual Destructor is that a Pure Virtual Destructor will make its Base class Abstract, which means that you will be unable to construct objects of that class.

It's not necessary for the derived classes to include pure virtual destructors.

What are the rules for defining a Destructor?

  1. The name should start with the tilde symbol (~) and match the class name.
  2. A class may not have more than one destructor.
  3. Destructors do not accept any parameters, in contrast to constructors, which may accept parameters.
  4. Like constructors, they don't have a return type.
  5. If a class doesn't have a destructor specified, the compiler creates one and puts it into your code.