初始化的类组件顺序

mat*_*att 11 c++ standards

class D: A
{
    B obj;
    C obj2;
}
Run Code Online (Sandbox Code Playgroud)

为了什么建设这里保证

我知道D将在A,B和C之后构建,但我真正想知道的是A是否保证在B或C之前构造,或者甚至是否保证在C之前构造B.

我知道你可以有一个明确的初始化列表:

D(): A(), B(), C()
{}
Run Code Online (Sandbox Code Playgroud)

但初始化列表是否确定了初始化的顺序

此外,是否有任何组件是否具有默认构造函数?

Ada*_*eld 10

来自C++ 03标准ISO/IEC 14882:2003(E)§12.6.2/ 5 [class.base.init]:

初始化应按以下顺序进行:
- 首先,并且仅对于如下所述的最派生类的构造函数,虚拟基类应按照它们在定向的深度优先从左到右的遍历中出现的顺序进行初始化.基类的非循环图,其中"从左到右"是派生类base-specifier-list中基类名称的出现顺序.
- 然后,直接基类应按声明顺序初始化,因为它们出现在base-specifier-list中(无论mem-initializers的顺序如何).
- 然后,非静态数据成员应按照它们在类定义中声明的顺序进行初始化(同样不管mem-initializers的顺序如何).
- 最后,执行构造函数的主体.
[ 注意:声明顺序的作用是确保以初始化的相反顺序销毁基础和成员子对象.]

因此,在这种情况下,您可以保证初始化的顺序首先是基类A,然后是子对象B(因为它首先出现在类定义的类成员列表中),然后是子对象C.初始化程序列表的顺序是无关紧要的,无论是否有任何成员都有或没有默认构造函数 - 如果成员没有默认构造函数并且它没有在初始化程序列表中显式初始化,那么它具有一个未指定的值.


Naw*_*waz 9

但初始化列表是否确定了初始化的顺序?

.初始化列表并不确定部件数据的初始化和基子对象(或多个)的顺序.成员按其声明的顺序初始化,并且基础子对象按其提及的顺序构建 - 从左到右:

struct A : B, C {}  //B is constructed before C
Run Code Online (Sandbox Code Playgroud)

此外,在成员数据的初始化之前构造基础子对象.

struct A : B, C 
{
      D d;
      E e;
};
Run Code Online (Sandbox Code Playgroud)

上面结构中的初始化顺序:

    B     =>    C      =>   d    =>   e   
subobject   subobject     member    member
Run Code Online (Sandbox Code Playgroud)

它们以相反的顺序被破坏.

  • @seand:另一个原因是成员的构造与他们的构造相反.如果不同的构造函数(通过它们的初始化列表)可以用不同的顺序构造成员,那么C++实现必须在某处存储一些秘密数据,以便它知道以后销毁它们的顺序.实际上,一旦构造了一个对象,实现就会忘记使用了哪个构造函数. (9认同)