tags:

views:

101

answers:

3

Let's say I have a basic class A that aggregate B and C:

class A  
{  
    B _b;  
    C _c;  
}

in what order are _b and _c going to be deleted?
I've read somewhere that it's the reverse order of their allocation.
So I guess in this little example _c is deleted before _b, right?

Now if I have a A constructor that looks like that:

A::A():  
_c(...),  
_b(...)  
{  
}

In what order are _b and _c's constructors called?
If _b's constructor is indeed called before _c's one (regarding their order in A), then I find it really counter intuitive!

In this case what will be the order of destruction?

Thanks for your help ! :)

(On a side note I seem totally unable to type '}' into Stackoverflow's editor. Had to copy and paste from an external editor !?)

+7  A: 

Non-static class members are always destroyed in the reverse order that they were constructed.

The order that members are constructed always matches the order that they are declared in the class definition. The order that members appear in a constructor's initalizer list has no effect on the order of their construction.

In your example _c is destroyed, then _b is destroyed, the reverse order of their declaration in the class.

Charles Bailey
Agreed. I would emphasize a bit more the fact the the order of declaration - and not the order in the initialization list - defines the order of construction.
RaphaelSP
@RaphaelSP: agreed and updated.
Charles Bailey
And I wish that C++ required that items in initializer lists be given in the initialization order. It would be a minor pain, but I think it would eliminate this irritating point of confusion. At the very least, I wish my tools would give me a refactoring command to do this (hell, even a compiler warning - can I get that from MSVC or GCC with some option?)
Michael Burr
GCC does warn about this with `-Wall`, but I'm not sure if there's a specific warning to turn this on.
Charles Bailey
+6  A: 

They are destroyed (not deleted) in the reverse order that they were created. It is this that also requires that regardless of how the constructor is written that all the members must be constructed in a consistent order. If each constructor could define the order that the members were constructed, each class instance would have to carry around information on how it was constructed, in order to be able to destruct in reverse order. By defining the order to always be the order that the members were declared in the class definition, the order of construction does not change from constructor to constructor.

In your example, first, memory is allocated for the full A class. Next _b is constructed, then _c then A. If A were to have a base class, that would be fully constructed before any of the above. On deletion, the reverse occurs. First A's destructor is called, then _c is destructed, then _b (then any base classes are destructed). Finally the memory for 'A' is freed.

Eclipse
Ok so do you mean that in my constructor example, _b's constructor is called before _c's ?
Julio
Yes, in your example _b's constructor is called first.
AndreyT
Ok thanks for the answer in your edit :)
Julio
Good to mention the rationale behind the construction order! +1
xtofl
A: 

class members constructors are always called in the order of their declaration, regardless the call order in the master class constructor.

in your case,

A::A():  
_c(...),  
_b(...)  
{  
}

implies the same construction/destruction order than

A::A():  
_b(...),
_c(...)  
{  
}
loic