Why are destructors called in reverse?

Pages: 12
From my book:

"Destructors for a derived class object are called in the reverse order of the constructors for the object. This is a general rule that always applies. Constructors are invoked starting with the base class constructor and then the derived class constructor, whereas the destructor for the derived class is called
first when an object is destroyed, followed by the base class destructor."

But why, or is it just because, so programmers know which one and modify their destructor accordingly??
I believe it is because in a class hierarchy, the derived classes may be using variables or data located i base classes. Is it not logical to initialize these first to ensure that the derived classes do not use invalid data? When we then destroy the objects; would it be logical to destroy "base" data whilst the derived destructor may still use this data in its destructor?

I believe this is the logical reasoning behind this rule. Think about it.
Stack. LIFO.
Can you show me a really small example of that being needed? The derived class using the base data in its destructor?
If the base class portion of a derived class were destroyed before the derived class version, the class instance would be in an undefined state. It would only be half-alive when the derived class destructor was called.

Maybe the base class has a container of some sort. The derived class writes the data in the container to a file when it's destructor is called. How does it write that data to file if the container no longer exists?

@keskiverto: Nothing to do with stacks.
I do disagree. The concept is very stack-like. The last constructed bit is destructed first.
Stack concept != having to do with stacks.
@cire

but wouldnt the container be destroyed right after? Literally right after?

But yea I guess it could lol

But what if they base class destructor wrote something to the container for the derived class destructor to do? How would that work?
Last edited on
Anmol444 wrote:
but wouldnt the container be destroyed right after? Literally right after?
Yes, which is why it has to write the data beforehand. If destructors were called in the same order as constructors, then you would be trying to write the data after the container was already destroyed. Too bad so sad, you don't have any valid data and all you get is garbage.
@L B

But the base class destructor would destroy the container right there and then after it writes to it, not right after but when the derived class constructor ends.
Please list the order in which you expect the destructors to be called in relation to the base class, the derived class, and the map inside the base class.
The map inside?

What map?

Anyways:

Base Constructor
Derived Constructor
Derived Destructor
Base Destructor

Based on what you guys said thats the order.
No, I meant the order you would have thought initially.
Anmol444 wrote:
What map?
I meant "container", the one we've been talking about.
True I would have thought of it like that initially.

I guess, so there isn't much of a reason behind it?

Its just so less confusion is found?
There is a massive important reason behind it, please read cire's post.
In this "If the base class portion of a derived class were destroyed before the derived class version, the class instance would be in an undefined state. It would only be half-alive when the derived class destructor was called. "

What does it mean half alive? And how would it be in undefined state?

I know alot of my questions are stupid, I aint a very smart person...
Last edited on
@Anmol444:
Please list order of construction and then destruction for 'box'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class T {};

class U {};

class A
{
  T t1;
  T t2;
};

class B : public A
{
  U u;
};

void main()
{
  B box;
}
A's constructor
T's constructor
U's constructor
B's constructor
B's destructor
U's destructor
T's destructor
A's destructor

Is that correct?
Not quite. Lets look at just the construction.

What about the t1 and t2? Yes, they are both of type T, but each calls constructor separately. Is there any ordering, or is it just random?

You construct box.u before calling box.B(), but also construct box.t[12] after calling box.A(). If you would create plain A ball;, what would be the order of ball.A() and ball.t1.T(), or does it matter?

Consider
1
2
3
4
A::A() : t2( 42 )
{
  t1 = 7;
}

Does that set some requirements for the order of construction?
Yea it makes T's constructor get called

then A's

Then T's

Is that correct?

For the older one:

A's constructor
T's constructor
T's constructor
B's constructor
U's constructor
U's destructor
B's destructor
T's destructor
T's destructor
A's destructor
Pages: 12