Order of member constructor and destructor calls
C++C++ Problem Overview
Oh C++ gurus, I seek thy wisdom. Speak standardese to me and tell my if C++ guarantees that the following program:
#include <iostream>
using namespace std;
struct A
{
A() { cout << "A::A" << endl; }
~A() { cout << "A::~" << endl; }
};
struct B
{
B() { cout << "B::B" << endl; }
~B() { cout << "B::~" << endl; }
};
struct C
{
C() { cout << "C::C" << endl; }
~C() { cout << "C::~" << endl; }
};
struct Aggregate
{
A a;
B b;
C c;
};
int main()
{
Aggregate a;
return 0;
}
will always produce
A::A
B::B
C::C
C::~
B::~
A::~
In other words, are members guaranteed to be initialized by order of declaration and destroyed in reverse order?
C++ Solutions
Solution 1 - C++
>In other words, are members guaranteed to be initialized by order of declaration and destroyed in reverse order?
Yes to both. See 12.6.2
> 6 Initialization shall proceed in the > following order: > > * First, and only for > the constructor of the most derived > class as described below, virtual base > classes shall be initialized in the > order they appear on a depth-first > left-to-right traversal of the > directed acyclic graph of base > classes, where “left-to-right” is the > order of appearance of the base class > names in the derived class > base-specifier-list. > > * Then, direct > base classes shall be initialized in > declaration order as they appear in > the base-specifier-list (regardless of > the order of the mem-initializers). > > * Then, non-static data members shall be > initialized in the order they were > declared in the class definition > (again regardless of the order of the > mem-initializers). > > * Finally, the > compound-statement of the constructor > body is executed. [ Note: the > declaration order is mandated to > ensure that base and member subobjects > are destroyed in the reverse order of > initialization. —end note ]
Solution 2 - C++
Yes, they are (non-static members that is). See 12.6.2/5 for initialization (construction) and 12.4/6 for destruction.
Solution 3 - C++
Yes, the standard guarantees objects get destructed in the reverse order they were created. The reason is that one object may use another, thus depend on it. Consider:
struct A { };
struct B {
A &a;
B(A& a) : a(a) { }
};
int main() {
A a;
B b(a);
}
If a
were to destruct before b
then b
would hold an invalid member reference. By destructing the objects in the reverse order in which they were created we guarantee correct destruction.
Solution 4 - C++
Yes and yes. The order of destruction is always opposite to the order of construction, for member variables.