哦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::~
换句话说,成员是否保证按声明顺序初始化并以相反的顺序销毁?
答案 0 :(得分:123)
换句话说,成员是否保证按声明顺序初始化并以相反的顺序销毁?
两者都是。见12.6.2
6 初始化应在 以下顺序:
首先,仅限于 派生最多的构造函数 类如下所述,虚拟基础 课程应在课程中初始化 命令它们出现在深度优先 从左到右遍历 有向无环图的基数 类,“从左到右”是 基类的出现顺序 派生类中的名称 基本符列表。
然后,直接 基类应初始化为 声明顺序,因为它们出现在 base-specifier-list(不管是什么 mem-initializers的顺序)。
然后,非静态数据成员应该是 按照他们的顺序初始化 在类定义中声明 (再次无论顺序如何 MEM-初始化)。
最后, 构造函数的复合语句 身体被执行。 [注意: 声明命令是强制性的 确保基础和成员子对象 以相反的顺序被摧毁 初始化。 - 尾注]
答案 1 :(得分:28)
是的,他们是(非静态成员)。初始化(构造)见12.6.2 / 5,销毁见12.4 / 6.
答案 2 :(得分:9)
是的,标准保证对象按照创建它们的相反顺序被破坏。原因是一个对象可能使用另一个对象,因此依赖于它。考虑:
struct A { };
struct B {
A &a;
B(A& a) : a(a) { }
};
int main() {
A a;
B b(a);
}
如果在a
之前b
要销毁,则b
将保留无效的成员引用。通过按照创建它们的相反顺序破坏对象,我们保证正确的破坏。
答案 3 :(得分:5)
是的,是的。对于成员变量,破坏的顺序总是与构造顺序相反。