Understanding Destructors in C++ – All You Need To Know
C++ is an object-oriented language that was first released in 1985 and has come a long way ever since. C++ is a language that is used in various fields like web development, game development, high-performance computing, data science, and in many other fields. C++ is an open-source language that is continually evolving and new features are being added with every new update.
One such feature is the destructors in C++. A destructor in C++ is a special member function that is called when an object is destroyed. They are automatically called when an object goes out of scope or is explicitly deleted. Let’s dive deeper and understand what exactly are destructors and how does it help.
What is a Destructor in C++?
Destructors in C++ are member functions of a class that are automatically called when an object of the class is deleted. They can also be explicitly invoked by using the delete command. The syntax for declaring a destructor is similar to other member functions, with only one difference: it should be preceded by a tilde (~). Destructors have no return type and do not accept any parameters.
The main purpose of a destructor is to free up resources associated with an instance of a class before its destruction. This includes releasing memory allocated dynamically, closing open files or sockets, and resetting variables back to their default values before deletion.
It’s important that all necessary operations are performed inside the destructor to avoid memory leaks or other errors due to dangling pointers after the object has been destroyed. You can gather your expertise in this field from a C and C++ programming course.
Utilities of a Destructor in C++
There are some common utilities that can be used in destructors in C++.
1. Delete Operator –
This operator is employed to remove objects that were built applying the modern operator. The delete operator requires one argument, which is a pointer to the entity to be deleted.
For instance, the code will delete an object of type MyClass:
MyClass* myObject = new MyClass();
// ...
delete myObject;
2. ~ Operator –
The ~ operator is utilized to invoke the destructor for an object. It does not take any arguments.
For instance, the code will call the destructor for an object of type MyClass:
MyClass* myObject = new MyClass();
// ...
~myObject;
3. The Delete Operator and the ~ Operator –
They can be employed together to delete objects that were utilized by leveraging the new operator. For instance, the code will remove an object of type MyClass and invoke its destructor:
MyClass* myObject = new MyClass();
// …
delete myObject;
Features of Destructor in C++
Here are some common features of destructor in C++:
- Destructors destroy the class objects built by the constructor.
- It has the same name identical to the class name prefixed with a tilde (~) sign.
- It is impossible to specify more than one destructor at a time.
- The destructor is a unique way to remove the object created by the constructor. Therefore destructor is unable to be overloaded.
- Destructor neither demands any argument nor returns any output.
- It is spontaneously invoked as soon as the object’s duration terminates.
- Destructor liberate storage filled by the objects created by the constructor
- In destructor, objects are destroyed in the reverse of object creation.
Examples of Destructor in C++
- This following code declares a class labeled “Example” using a constructor and a destructor. Whenever an object from the class is generated inside the primary function, the constructor is invoked and prints “Inside Constructor”. When the object goes to the end of the scope, the destructor is called and prints “Inside Destructor”.
#include <iostream>
using namespace std;
class Example {
public:
Example() {
cout << "Inside Constructor" << endl;
}
~Example() {
cout << "Inside Destructor" << endl;
}
};
int main() {
Example d;
return 0;
}
- Here, the constructor is triggered when the object is made, and the destructor is invoked when the object is destroyed. The destructor shows the message “Inside Destructor” on the screen. You can modify the meaning of the variables num1 and num2 to any symbols, names, identifiers, or constants you want. Furthermore, You can add more code to the constructor and destructor.
class Demo {
private:
int num1 = 10;
int num2 = 20;
public:
Demo() {
cout << "Inside Constructor" << endl;
}
void display() {
cout << "num1 = " << num1 << endl;
cout << "num2 = " << num2 << endl;
}
~Demo() {
cout << "Inside Destructor";
}
};
Output:
Inside Constructor
num1 = 10
num2 = 20
Inside Destructor
Syntax of Destructor in C++
It points to the instructions and specifications for constructing statements in a programming language. They can alternatively be seen as the syntactic standards defining the structure of a programming language.
The C++ language also incorporates its syntax for the functionalities it offers. Different statements exhibit distinct syntax defining their usage but C++ programs also have fundamental syntax conditions that are maintained throughout all the programs.
Let’s take an example of syntax in C++ :
// C++ program to demonstrate the basic syntax
// Header File Library
#include <iostream>
// Standard Namespace
using namespace std;
// Main Function
int main()
{
// Body of the Function
// Declaration of Variable
int num1 = 50;
int num2 = 100;
int result = num1 + num2;
// Output
cout << result << endl;
// Return Statement
return 0;
}
Output:
150
The following code is a C++ program that illustrates the fundamental syntax. It combines two numbers, num1, and num2, and saves the outcome within the variable result. The outcome is then printed employing the cout statement. The code displays the product as “150”.
What is a Virtual Destructor in C++?
A virtual destructor is a special member function in C++ classes that allows for the proper destruction of objects, even when they are deleted through base-class pointers. Virtual destructors are used to make sure that the correct destructor is called when an object is deleted through a pointer to its base class.
A virtual destructor in C++ is declared using a virtual keyboard. Additionally, a virtual destructor must be defined in every class wherever it is declared. In C++, virtual destructors are a crucial tool for avoiding memory leaks and other mistakes. For instance, the following program leads to unspecified behavior.
// CPP program without a virtual destructor
// causing undefined behavior
#include <iostream>
using namespace std;
class base {
public:
int x;
base() {
cout << "Constructing base\n";
}
~base() {
cout << "Destructing base\n";
}
};
class derived: public base {
public:
int y;
derived() {
cout << "Constructing derived\n";
}
~derived() {
cout << "Destructing derived\n";
}
};
int main() {
derived *d = new derived();
base *b = d;
delete b;
getchar();
return 0;
}
Output:
Constructing base
Constructing derived
Destructing derived
The digits, values, and variables have been altered to 1, 2, and 3 correspondingly. The result is also distinct because of the change in the numbers.
Nonetheless, this code will also result in ambiguous behavior because word the base class does not have a virtual destructor. This implies that when the delete operator is invoked on the base* pointer b, the destructor for the derived class will not be triggered. This can result in memory leaks and other issues.
To resolve this, you can include a virtual destructor in the base class:
class base {
public:
int x;
virtual ~base() {
cout << "Destructing base\n";
}
};
This will guarantee that the destructor for the derived class is executed when the delete operator is activated on the base* pointer b.
Difference between Constructor and Destructor in C++
The key comparisons between Constructor and Destructor are given below:
Constructor | Destructor |
Constructor supports setting up the object of a class. | While the destructor is utilized to terminate the instances. |
It is defined like className( arguments if any ){Constructor’s Body }. | On the other hand, it is identified as ~ className( no arguments ){ }. |
It either can receive an argument or not. | It doesn’t have any argument. |
When an instance of a class is built, a constructor is called. | When an instance of a class is deleted, a destructor is called. |
It can be overloaded during the development phase. | It doesn’t get overloaded. |
It has the same class name as the constructor name. | It has also the same class name as the constructor name but is preceded by the tiled (~) operator. |
It has multiple constructors | It has a single destructor |
Properties of Destructors in C++
Here are the properties of C++ destructors:
- Destructors are unable to be overloaded. It can’t have two destructors together with the same class and same name.
- Destructors are not allowed to be Const or volatile. This is due to destructors being invoked independently, and there is no chance to prevent them from being called.
- Destructors don’t have parameters because destructors do not require any data from the external world database to do their task.
- Destructors do not have a return type. This is because destructors do not return anything to the input.
- Destructors cannot be invoked through direct intervention. This signifies that you should not call a destructor yourself. Destructors are just requested by themselves.
- Destructors are called inherently as soon as an object leaves the scope or is specifically eliminated by a call to delete. This signifies that you do not require to do anything to invoke a destructor. It will be invoked automatically when the object is no longer required.
- Destructors are employed to free reserves that were designated by the object. This storage storage, documents, and network links.
- Destructors are applied to organize all data that was formed by the object. This includes terminating files, freeing memory space, and resetting variables.
Conclusion
Destructors in C++ have a vital role by spontaneously activating into action when objects have completed their role. In this blog, we delved into the subject, and grasped their syntax, talked about virtual destructors, compared and contrasted them with constructors, and emphasized the important properties of destructors.