C++ Destructors
In this tutorial, we will learn about the C++ destructor, Virtual and Pure virtual destructor with the help examples and when does destructor called and its rules.
Destructor
Destructor is a member function which deletes an object. A destructor is called automatically by the compiler when the object goes out of scope. A destructor is a special member function that works just opposite to constructor, unlike constructors that are used for initializing an object, destructors destroy (or delete) the object.
A destructor works opposite to constructor and defined like constructor; it destructs the objects of classes. It can be defined only once in a class and must have same name as class. Like constructors, it is invoked automatically. But it is prefixed with a tilde sign (~).
Syntax:
~className{
// Some code
};
Note: C++ destructor cannot have parameters. Moreover, modifiers can't be applied on destructors.
Properties of Destructor
A constructor is different from normal functions in following ways:
- Destructor function is automatically invoked when the objects are destroyed.
- It cannot be declared static or const.
- The destructor does not have arguments.
- It has no return type not even void.
- An object of a class with a Destructor cannot become a member of the union.
- A destructor should be declared in the public section of the class.
- The programmer cannot access the address of destructor.
When does the destructor get called?
A destructor function is called automatically when the object goes out of scope:
(1) When the function ends.
(2) When the program ends.
(3) When a scope (the { } parenthesis) containing local variable ends.
(4) When a delete operator is called.
How destructors are different from a normal member function?
A destructor is different from normal functions in following ways:
- Destructors have same name as the class but is preceded by a tilde (~).
- Destructors have no argument and no return value.
Example 1: C++ program to demonstrate the use of Destructor
#include <iostream>
using namespace std;
// declare a class
class hello {
public:
// Constructor
hello() {
cout << "Constructor is Called." << endl;
}
// Destructor
~hello() {
cout << "Destructor is Called." << endl;
}
// Member Function
int display(){
cout << "Hello, Programmer." << endl;
}
};
int main() {
// create an object
hello obj1;
// Member function called
obj.display();
return 0;
}
Output
Constructor is Called. Hello, Programmer. Destructor is Called.
Virtual Destructors in C++
Deleting a derived class object using a pointer of base class type that has a non-virtual destructor results in undefined behavior. To correct this situation, the base class should be defined with a virtual destructor.
Destructors in the Base class can be Virtual. Whenever Upcasting is done, Destructors of the Base class must be made virtual for proper destrucstion of the object when the program exits.
NOTE: Constructors never be Virtual, only Destructors can be Virtual.
For Example:-
Example 2: C++ program for Upcasting without virtual destroctor
To print the content of a void pointer, we use the static_cast
operator. It converts the pointer from void*
type to the respective data type of the address the pointer is storing:
#include <iostream>
using namespace std;
// declare a class
class base {
public:
// Destructor
~base() {
cout << "Destructor base." << endl;
}
};
class derived : publicbase {
public:
// Destructor
~derived() {
cout << "Destructor derived." << endl;
}
}
int main() {
base* b = new derived; // Upcasting
delete b;
return 0;
}
Output
Destructor base.
In the above example, delete b
will only call the Base class destructor, which is undesirable because, then the object of Derived class remains undestructed, because its destructor is never called. Which results in memory leak.
Example 3: C++ program for Upcasting with virtual destroctor
#include <iostream>
using namespace std;
// declare a class
class base {
public:
virtual ~base() {
cout << "Destructor base." << endl;
}
};
class derived : publicbase {
public:
~derived() {
cout << "Destructor derived." << endl;
}
}
int main() {
base* b = new derived; // Upcasting
delete b;
return 0;
}
Output
Destructor base. Destructor derived.
When we have Virtual destructor inside the base class, then first Derived class's destructor is called and then Base class's destructor is called, which is the desired behaviour.
Pure Virtual Destructor
When a destructor is initialized with value 0. It is called virtual destructor, it is declared in base class. Like virtual destructor, pure virtual destructor is also possible. But it should be defined in base class.
- The only difference between Virtual and Pure Virtual Destructor is, that pure virtual destructor will make its Base class Abstract, hence you cannot create object of that class.
- There is no requirement of implementing pure virtual destructors in the derived classes.
Example 4: C++ program to understand Pure virtual destroctor
#include <iostream>
using namespace std;
// declare a class
class base {
public:
virtual ~base() = 0; // Pure Virtual Destructor
};
// Definition of Pure Virtual Destructor
base :: ~base() {
cout << "Pure virtual destructor is called.\n";
}
class derived : publicbase {
public:
~derived() {
cout << "Derived Destructor is called." << endl;
}
}
int main() {
base* b = new derived;
delete b;
return 0;
}
Output
Pure virtual destructor is called. Derived Destructor is called.
Rules for defining a Destructor
1) Name should begin with tilde sign(~) and must match class name.
2) There cannot be more than one destructor in a class.
3) Unlike constructors that can have parameters, destructors do not allow any parameter.
4) They do not have any return type, just like constructors.
5) When you do not specify any destructor in a class, compiler generates a default destructor and inserts it into your code.
Important Question / Answers
1. Is there be more than one destructor in a class?
Ans :-) No, there can only one destructor in a class with className preceded by 'tilde sign' ~
, no parameters and no return type.
2. When do we need to write a user-defined destructor?
Ans :-) If we do not write our own destructor in class, compiler creates a default destructor for us. The default destructor works fine unless we have dynamically allocated memory or pointer in class. When a class contains a pointer to memory allocated in class, we should write a destructor to release memory before the class instance is destroyed. This must be done to avoid memory leak.
Next Tutorial
We hope that this tutorial helped you develop better understanding of the concept of Destructors in C++.
Keep Learning : )
In the next tutorial, you'll learn about C++ Constructor Overloading
.