In C++ programming language, a destructor works just opposite to constructor. It is used to destroy the objects of classes. It can be defined only once in a class. Like constructors, it is called automatically.
A destructor is defined as a constructor . It must have the same name as the class. But it is prefixed with a tilde sign (~).
Note: C++ destructor cannot have parameters. Moreover, modifiers can't be applied to destructors.
Syntax
In C++ programming language , destructors are automatically available in each class, but we can redefine them by following syntax.
~className(){
// Body of destructor
}
Where
- tilde(~) is utilized to form the destructor of a className.
Similar to any other member function of the class, we can also declare the destructor outside the class:
className {
public:
~className();
}
class-name :: ~className() {
// Desctructor Body
}
C++ Destructor Example
Let's take an example to illustrate the constructor and destructor in C++ which is called automatically.
Example
#include <iostream>
using namespace std; //using standard namespace
class Employee
{
public:
Employee()
{
cout<<"Constructor Invoked"<<endl;
}
~Employee()
{
cout<<"Destructor Invoked"<<endl;
}
};
int main(void) //main function
{
Employee e1; //creating an object of Employee
Employee e2; //creating an object of Employee
return 0;
}
Output:
Constructor Invoked
Constructor Invoked
Destructor Invoked
Destructor Invoked
Explanation:
In this example, we have taken an Employee class that has a constructor and a destructor. When two objects (e1 and e2) are created in the main function, the constructor is called twice. When the program ends, the destructor is automatically invoked for both objects in reverse order of their creation.
When do we have to write a user-defined destructor?
If we define our destructor in class, the compiler automatically generates a default destructor for a program. The default destructor is perfect unless we have dynamically allocated memory or pointers in class. In such cases, a custom destructor is needed to release the memory and prevent memory leaks.
User-defined Destructor Example in C++
Let us take an example to illustrate the user-defined destructor in C++.
Example
#include <iostream>
#include <cstring>
using namespace std; //using standard namespace
class Student {
char* name;
public:
Student(const char* studentName) {
name = new char[strlen(studentName) + 1];
strcpy(name, studentName);
cout << "Constructor: Memory allocated for name\n";
}
~Student() {
delete[] name;
cout << "Destructor: Memory deallocated for name\n";
}
void display() {
cout << "Student Name: " << name << endl;
}
};
int main() { //main function
Student s1("David");
s1.display();
return 0;
}
Output:
Constructor: Memory allocated for name
Student Name: David
Destructor: Memory deallocated for name
Explanation:
In this example, we have taken a Student class that dynamically allocates memory for a name. After that, a constructor makes a copy of the name, and the destructor deallocates the memory allocated for it. In the main function, an object named "David" is declared, printed, and then automatically cleaned up.
Virtual Destructors in C++
In C++, a virtual destructor is an undefined behaviour that is mainly utilized to delete a derived class object by using base class pointer object. A base class destructor uses the virtual keyword that ensures both the base class and the derived class destructor that will be called at run time, but it calls the derived class first and followed by the base class to release the space that is occupied by both destructors.
Virtual Destructor Example in C++
Let us take an example to illustrate the virtual destructor in C++.
Example
#include <iostream>
using namespace std; //using standard namespace
class Base {
public:
Base() {
cout << "Base Constructor\n";
}
virtual ~Base() {
cout << "Base Destructor\n";
}
};
class Derived : public Base {
public:
Derived() {
cout << "Derived Constructor\n";
}
~Derived() {
cout << "Derived Destructor\n";
}
};
int main() { //main function
Base* ptr = new Derived();
delete ptr;
return 0;
}
Output:
Base Constructor
Derived Constructor
Derived Destructor
Base Destructor
Explanation:
In this example, we have taken a base class with a virtual destructor and a derived class that inherits from it. After that, a pointer to the base class points to an object of the derived class. Both derived and base destructors are called when it is deleted because the base destructor is declared as virtual, so cleanup in inheritance is correct.
Pure Virtual Destructor
In C++ programming, a pure virtual destructor is a special type of destructor that is declared in an abstract base class using the = 0 syntax, just like a pure virtual function. It makes the class abstract, which means that the objects of that class cannot be instantiated. However, even if we declared a function as pure, it must have a body (definition) because destructors are always called when objects are destroyed.
The only distinction between Virtual and Pure Virtual Destructor is that a pure virtual destructor will declare its Base class Abstract. Thus, we cannot make the object of that class. There is no need for the implementation of pure virtual destructors in the derived classes.
Pure Virtual Destructor Example in C++
Let us take an example to illustrate the pure virtual destructor in C++.
Example
#include <iostream>
using namespace std; //using standard namespace
class Base {
public:
virtual ~Base() = 0; //pure virtual destructor
};
Base::~Base() {
cout << "Base destructor called\n";
}
class Derived : public Base {
public:
~Derived() {
cout << "Derived destructor called\n";
}
};
int main() { //main function
Base* ptr = new Derived();
delete ptr;
return 0;
}
Output:
Derived destructor called
Base destructor called
Explanation:
In this example, we demonstrate a pure virtual destructor in the base class, which makes it abstract. After that, the destructor is still defined outside the class to ensure proper cleanup. When a Derived object is deleted through a Base pointer, both destructors are called in the correct order, which ensures safe destruction.
Features of Destructor in C++
Several features of a destructor in C++ are as follows:
- Destructor name should be the same as their class name with a tilde (~) symbol prefixed.
- It cannot be defined more than once.
- Destructor is only one method of terminating the object formed by the constructor. So the destructor can't be overloaded.
- It cannot be declared as static or constant.
- The destructor doesn't take any argument and also doesn't return any value.
- It is invoked automatically when an object goes out of scope.
- Destructors free the memory space that is held by the objects that the constructor created.
- In the destructor, objects are destroyed in the reverse order of their creation.
When the destructor is executed?
A destructor function is automatically invoked when the object goes out of scope or is deleted. There are several cases when we call the destructor in C++.
- In C++ programming, a destructor is invoked when the function ends.
- A destructor is invoked when a block that holds local variables is finished.
- Destructor is invoked when a delete operator is invoked.
C++ Destructors FAQs
1) What is a destructor in C++?
In C++, a destructor is a special member function that is called automatically when an object goes out of scope or gets deleted, used to free resources.
2) When is a destructor invoked?
It is invoked automatically when we want to destroy an object, either when it goes out of scope or delete is invoked.
3) Can we contain more than one destructor in a class in C++?
No, there can be only one destructor in a class, and it cannot be overloaded.
4) What does the syntax of a destructor look like in C++?
It is a tilde (~) and then the class name: ~ClassName.
5) What is a virtual destructor in C++?
In C++, a virtual destructor is an undefined behaviour that is used to delete a derived class object by using base class pointer object.