C++ class, destructor
In C++, a destructor is a special member function of a class that is executed when an object of the class goes out of scope or is explicitly deleted. The purpose of a destructor is to release resources that the object may have acquired during its lifetime.
Syntax of a Destructor:class ClassName {
public:
~ClassName() {
// Cleanup code here
}
};
Virtual Destructors
A virtual destructor ensures that the destructor of a derived class is called when an object is deleted through a base class pointer. This is important for proper resource management in polymorphic classes. When a base class has a virtual destructor, the destructor of the derived class is called first, followed by the destructor of the base class.
Syntax of a Virtual Destructor:class Base {
public:
virtual ~Base() {
// Cleanup code here
}
};
Code Example
Explanation
Class Definitions:
struct Base1 {
~Base1() {
std::cout << "Base1 destructor called." << std::endl;
}
};
struct Base2 {
virtual ~Base2() {
std::cout << "Base2 destructor called." << std::endl;
}
};
struct Derived1 : Base1 {
~Derived1() {
std::cout << "Derived1 destructor called." << std::endl;
}
};
struct Derived2 : Base2 {
~Derived2() {
std::cout << "Derived2 destructor called." << std::endl;
}
};
- Base1 has a non-virtual destructor.
- Base2 has a virtual destructor.
- Derived1 and Derived2 are derived classes from Base1 and Base2, respectively.
Main Function:
Without Virtual Destructor:Base1* p1 = new Derived1();
delete p1;
Here, a Base1 pointer is used to point to a Derived1 object. When delete p1 is called, only the Base1 destructor is executed, and the Derived1 destructor is not called. This can lead to resource leaks if the derived class has resources that need to be released.
With Virtual Destructor:Base2* p2 = new Derived2();
delete p2;
In this case, a Base2 pointer points to a Derived2 object. When delete p2 is called, the Derived2 destructor is called first, followed by the Base2 destructor. This ensures that any resources acquired by the derived class are properly released.
Output:
Base1 without virtual destructor
Base1 destructor called.
Base2 with virtual destructor
Derived2 destructor called.
Base2 destructor called.
As we can see from the output:
- When deleting the Base1 pointer to a Derived1 object, only the Base1 destructor is called.
- When deleting the Base2 pointer to a Derived2 object, both the Derived2 destructor and the Base2 destructor are called in the correct order.
Conclusion
Using virtual destructors in C++ is essential when dealing with polymorphic base classes to ensure proper cleanup of resources. Always declare destructors as virtual in base classes that are meant to be extended.