Destructor
Destructors are the opposite of Constructors. They’re a special member function that is executed automatically when an object is destroyed.
- Used to deallocate the memory that has been allocated for the object by the constructor
In C++
The destructor is the same name as the class, with a ~
in front.
Object destruction sequence (this is the inverse of Constructor order)
- Destructor body runs
- Object fields have their destructors run in reverse declaration order
- Superclass destructor runs
- Space is reclaimed
Use Virtual Destructors!!
Destructors are usually declared as Virtual Methods though technically they can’t be overridden.
Always use
virtual
Unless you are sure a class will never be subclassed, then always declare your destructors as virtual.
If you are sure that your class will never be subclassed, enforce it via the final keyword.
Motivation through example
The motivation for this was seen in CS247, through the following example:
Which of these leaks memory?
Object destruction sequence:
- Destructor body runs
- Object fields have their destructors run in reverse declaration order
- Superclass destructor runs
- Space is reclaimed
Because the destructor is non-virtual, for pxy
, we invoke ~X
, not the ~Y
, so this array b
is leaked.
- This is confusing, see Virtual Method
- If we do declare it the superclass destructor as virtual, it knows to look for the derived class’s implementation of the destructor. Thus, it would first calls
~Y
(derived class’s destructor), and then it ALSO calls~X
(superclass destructor).- in this case, it doesn’t matter that the names of the destructors are different. Both derived and parent destructors will be called
Solution: declare virtual ~X()
, so delete pxy
calls ~Y()
.
Therefore, unless you are sure a class will never be subclassed, then ALWAYS declare your destructors as virtual.
If you are sure, enforce it via the final keyword.
Why are destructors declared as
virtual
, but not constructors?I think it is because of the way we are achieving Polymorphism. Consider something like
Base* b = new Derived{}
. Only theDerived
constructor gets called here.Also some better explanations in StackOverflow and Quora.
When does a destructor get called?
When does a destructor get called? When the variable goes out of scope.
What if there are multiple destructors to call?
Destructors are called in reverse order of their creation.
In this example (from Observer Pattern), the destructor for wario
gets called first, followed by joe
, and finally elon
.