Max*_*xpm 18 c++ initialization standards-compliance undefined-behavior ctor-initializer
这种行为定义明确吗?
class Foo
{
int A, B;
public:
Foo(int Bar): B(Bar), A(B + 123)
{
}
};
int main()
{
Foo MyFoo(0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GMa*_*ckG 18
不,这是未定义的.A将首先初始化(它是类定义中的第一个),它使用未初始化B.
类成员按它们在类定义中出现的顺序初始化,而不管它们在初始化列表中的顺序如何.实际上,将成员定义顺序与初始化列表顺序不匹配是不好的做法.
如果您的实例Foo恰好具有静态持续时间,例如Foo f(0); int main(){},则行为是明确定义的.具有静态持续时间的对象在进行任何其他初始化之前进行零初始化; 在这种情况下,A并B运行该构造函数时将是0.在那之后,虽然,行为是相同的:第一A然后B,给人A的123的值和B的值Bar(静止难看).
Xeo*_*Xeo 12
不,初始化顺序由类本身的声明顺序定义.
从C++标准12.6.2 [class.base.init] p5:
初始化应按以下顺序进行:
- 首先,并且仅对于如下所述的最派生类的构造函数,虚拟基类应按照它们在定向的深度优先从左到右的遍历中出现的顺序进行初始化.基类的非循环图,其中"从左到右"是派生类base-specifier-list中基类名称的出现顺序.
- 然后,直接基类应按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何).
- 然后,非静态数据成员应按照它们在类定义中声明的顺序进行初始化(同样不管mem-initializers的顺序如何).
- 最后,执行构造函数的主体.
[注意:声明顺序的作用是确保以初始化的相反顺序销毁基础和成员子对象.]