Sanane Lan
Sanane Lan

Reputation: 103

How does the compiler handle base class destructor calls in the derived destructor?

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

Answers (3)

Anton
Anton

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

roman
roman

Reputation: 105

Calling derived class virtual destructor causes call of base class destructor. But not vise versa.

Upvotes: 0

Sebastian Redl
Sebastian Redl

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

Related Questions