Reputation: 103
Just out of curiosity I tried to do something like the example below to see if the compiler gives me a warning or so instead of calling an endless loop which ends up in a stack overflow. I thought maybe there is a different behavior than just calling normal functions or methods. But that's not the case. Is there a special explanation for that or is it just handled as normal function calls since I am explicitely calling the base class destructor by using the this
operator?
Example:
class A {
virtual ~A();
};
class B : A {
virtual ~B() { this->~A(); }
};
Upvotes: 1
Views: 191
Reputation: 1538
Virtual destructors in a derived class will always call parent-class destructors first, in a recursive order such that the most "ancestral" base-class' destructor will be called, and then the second-most-"ancestral", etc. Imagine that Child inherits from Parent, which inherits from GrandParent. The Child class' destructor will actually call GrandParent's destructor, then Parent's destructor, then Child's destructor.
Indeed your derived class constructors also call their parent-class constructors in the same recursive order. You have to imagine derived classes like a "layer cake": each instance of inheritance adds a layer to your object. So the Child class has 3 layers {GrandParent, Parent, Child}, each layer's construction/destruction is handled by the corresponding class.
What you're attempting will attempt to call the parent destructor twice, which is a bad idea. Generally you do not have to explicitly call destructors, except in the case where you overloaded the new
operator. See this answer for more details: Is calling destructor manually always a sign of bad design?
Upvotes: 1
Reputation: 105
Calling derived class virtual destructor causes call of base class destructor. But not vise versa.
Upvotes: 0
Reputation: 72063
@M.M's comment hit it. You are calling the destructor twice. This is undefined behavior and anything may happen, including the behavior you observe.
(In reality, most likely one of those destructor calls modifies the vptr of the object, meaning that subsequent destructor calls no longer go to the most derived object. But that's just a guess.)
The correct thing to do is to not call the destructor manually.
Upvotes: 2