C++ 类数据成员的初始化顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2669888/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:17:14  来源:igfitidea点击:

Initialization Order of Class Data Members

c++initializationclass-members

提问by Nikhil

In the following code, when the ctor of Xis called will the ctor of Aor Bbe called first? Does the order in which they are placed in the body of the class control this? If somebody can provide a snippet of text from the C++ standard that talks about this issue, that would be perfect.

在下面的代码中,当X调用 ctor of 时AB会先调用or的 ctor吗?它们在类主体中的放置顺序是否会控制这一点?如果有人可以提供 C++ 标准中讨论此问题的文本片段,那就太完美了。

class A {};
class B {};
class X
{
 A a;
 B b;
};

回答by

The order is the order they appear in the class definition - this is from section 12.6.2 of the C++ Standard:

顺序是它们在类定义中出现的顺序 - 这是来自 C++ 标准的第 12.6.2 节:

5 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, nonstatic 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 body of the constructor is executed. [Note: the declaration order is mandated to ensure that base and member subobjects are destroyed in the reverse order of initialization. ]

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

— 首先,并且仅对于如下所述的最派生类的构造函数,虚拟基类应按照它们出现在基类的有向无环图的深度优先从左到右遍历中出现的顺序进行初始化,其中“从左到右”是派生类基类说明符列表中基类名称的出现顺序。

— 然后,直接基类应按照它们出现在基说明符列表中的声明顺序进行初始化(不管内存初始化器的顺序如何)。

— 然后,非静态数据成员应按照它们在类定义中声明的顺序进行初始化(同样与 mem 初始化程序的顺序无关)。

— 最后,执行构造函数的主体。[注意:声明顺序是为了确保基类和成员子对象以与初始化相反的顺序销毁。]

回答by CB Bailey

Initialization is always in the order that the class members appear in your class definition, so in your example a, then b.

初始化始终按照类成员在类定义中出现的顺序进行,因此在您的示例中a,则b.

There is a sequence point between the initialization of each member and you canpass a reference to a yet-to-be initialized member into the constructor of a class member but you would only be able to use it in limited ways (such as taking its address to form a pointer), other uses may well cause undefined behaviour.

每个成员的初始化之间有一个序列点,您可以将尚未初始化的成员的引用传递给类成员的构造函数,但您只能以有限的方式使用它(例如将其地址以形成指针),其他用途很可能会导致未定义的行为。

Destruction of class members always happens in the reverse order of construction.

类成员的销毁总是以与构造相反的顺序发生。

Order of initialization of bases and members is defined in 12.6.2 [class.base.init]/5.

基类和成员的初始化顺序在 12.6.2 [class.base.init]/5 中定义。