成员构造函数和析构函数调用的顺序

哦,C ++大师,我寻求你的智慧。 对我说标准并告诉我,如果C ++保证以下程序:

#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; } 

将永远生产

 A::A B::B C::C C::~ B::~ A::~ 

换句话说,成员是否保证按声明的顺序进行初始化,并以相反的顺序销毁?

换句话说,成员是否保证按声明的顺序进行初始化,并以相反的顺序销毁?

对两者都是。 见12.6.2

6初始化应按以下顺序进行:

  • 首先,对于下面描述的派生类最多的构造函数,虚拟基类应按照它们出现在基类的有向无环图的深度优先从左到右遍历的顺序进行初始化,其中“左从右到左“是派生类base-specifier-list中基类名的出现顺序。

  • 然后,直接基类应按声明顺序进行初始化,因为它们出现在base-specifier-list中(不pipemem-initializer的顺序如何)。

  • 然后,非静态数据成员应按照它们在类定义中声明的顺序进行初始化(不pipemem初始化的顺序如何)。

  • 最后,执行构造函数体的复合语句。 [注意:声明顺序要求确保基本和成员子对象按照初始化的相反顺序销毁。 – 注意]

是的,他们是(非静态成员)。 初始化(构造)见12.6.2 / 5,破坏见12.4 / 6。

是的,标准保证对象按照与创build相反的顺序被破坏。 原因是一个对象可能使用另一个对象,因此依赖于它。 考虑:

 struct A { }; struct B { A &a; B(A& a) : a(a) { } }; int main() { A a; B b(a); } 

如果ab之前被破坏,则b将持有无效的成员引用。 通过以相反的顺序破坏对象,我们保证正确的销毁。

是的,是的。 对于成员variables,销毁顺序总是与构造顺序相反。