我有一个带有一些参数的构造函数。我假设它们是按照列出的顺序初始化的,但在一种情况下,它们似乎是按相反的顺序初始化的,导致中止。当我颠倒参数时,程序停止中止。
下面是我正在使用的语法的示例。在这种情况下,需要在
a_
之前初始化 b_
。你能保证这个初始化顺序吗?
class A
{
public:
OtherClass a_;
AnotherClass b_;
A(OtherClass o, string x, int y)
: a_(o)
, b_(a_, x, y) {}
};
这取决于类中数据成员声明的顺序。因此
a_
将是您示例中的第一个,然后 b_
将是第二个。
为了澄清,该标准在 class.base.init 下规定:
在非委托构造函数中,初始化按以下顺序进行:
...
- 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(同样不管内存初始化器的顺序)。
现在的标准参考似乎是 12.6.2 第 13.3 节:
(13.3) — 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化 (同样无论内存初始化器的顺序如何)。
查看其他答案,而无需了解其他成员初始化的详细信息,我建议阅读标准参考 12.6.2 第 13 节中的更多信息(感谢@Adam Getchell 提供链接):
术语:在非委托构造函数中,初始化按以下顺序进行:
(13.1) — 首先,且仅适用于 最底层派生类的构造函数 (1.8),
(13.2) — 然后,
虚拟基类在中初始化 它们在基类有向无环图的深度优先从左到右遍历中出现的顺序, 其中“从左到右”是派生类中基类的出现顺序base-specifier-list。直接基类按声明顺序初始化
(13.3) — 然后,
它们出现在 base-specifier-list 中 (无论
mem-initializers 的顺序如何)。非静态数据成员被初始化
(13.4) — 最后,执行构造函数主体的
按照它们在类定义中声明的顺序 (同样无论
mem-initializers 的顺序如何)。compound-statement。
base-specifier-list
class A :
public virtual B, private C
mem-initializers
A::A() :
number(1.0f), text("abc")
{ /* ... */}
compound-statement
{}
的块,即构造函数的主体。