Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类组件初始化顺序_C++_Standards - Fatal编程技术网

C++ 类组件初始化顺序

C++ 类组件初始化顺序,c++,standards,C++,Standards,这里保证什么样的施工顺序 我知道D将在A、B和C之后构造,但我真正想知道的是A是否保证在B或C之前构造,甚至B是否保证在C之前构造 我知道你可以有一个明确的初始化列表: class D: A { B obj; C obj2; } 但是初始化器列表决定了初始化的顺序吗 此外,是否有任何组件有或没有默认构造函数 但是初始化列表决定了初始化的顺序吗 否。初始化列表不确定成员数据和基本子对象的初始化顺序。成员按声明的顺序初始化,基子对象按提及的顺序构造(从左到右): D(): A(),

这里保证什么样的施工顺序

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

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

class D: A
{
    B obj;
    C obj2;
}
但是初始化器列表决定了初始化的顺序吗

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

但是初始化列表决定了初始化的顺序吗

。初始化列表不确定成员数据和基本子对象的初始化顺序。成员按声明的顺序初始化,基子对象按提及的顺序构造(从左到右):

D(): A(), B(), C()
{}
此外,基本子对象是在成员数据初始化之前构造的

struct A : B, C {}  //B is constructed before C
上述结构中的初始化顺序:

struct A : B, C 
{
      D d;
      E e;
};

而它们是按相反的顺序被破坏的。

也许这个破坏代码的例子将有助于说明:

如果我这样定义一个类:

    B     =>    C      =>   d    =>   e   
subobject   subobject     member    member
这将在所有现代编译器中失败。由于
\u socket
首先定义为类成员,因此初始化列表将尝试首先初始化它,尽管初始化列表要求编译器首先初始化
\u io\u服务。但是由于
\u io_服务
尚未初始化(套接字构造函数取决于已初始化的
\u io_服务
),因此
\u套接字
的初始化将导致segfault

也许有人可以引用标准中规定这种行为的适当部分


对于问题的后半部分,基类总是在类自己的成员之前初始化。

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

初始化应按以下顺序进行:
-首先,并且仅针对如下所述的最派生类的构造函数,虚拟基类应按照它们在基类的有向无环图的深度优先的从左到右遍历中出现的顺序进行初始化,其中“从左到右”基类名称在派生类基类说明符列表中的出现顺序。
-然后,直接基类应按照它们在基说明符列表中出现的声明顺序进行初始化(无论mem初始值设定项的顺序如何)。
-然后,应按照类定义中声明的顺序初始化非静态数据成员(同样,与mem初始值设定项的顺序无关)。
-最后,将执行构造函数的主体。
[注意:声明顺序是为了确保基本子对象和成员子对象按与初始化相反的顺序销毁。]


因此,在这种情况下,可以保证初始化顺序将首先是基类
A
,然后是子对象
B
(因为它首先出现在类定义中的类成员列表中),然后是子对象
C
。初始值设定项列表的顺序无关紧要,任何成员是否有默认构造函数也无关紧要。如果成员没有默认构造函数,并且未在初始值设定项列表中显式初始化,则该成员具有未指定的值。

要澄清,声明的顺序控制着初始化的顺序好吧,那么基类和成员对象呢,是否保证初始化?我猜从技术上讲基类是在成员之前声明的,那么这是否意味着是声明控制init顺序的原因是它防止了可能的歧义。如果两个actor具有不同顺序的init列表呢。始终保持顺序一致以避免混淆是一种很好的做法。@seand:另一个原因是成员按与其构造相反的顺序被破坏。如果不同构造函数(通过它们的初始化列表)可以构造不同顺序的成员,那么C++实现将必须存储一些秘密数据,以便它知道以后要销毁它们的顺序。事实上,一旦构造了一个对象,实现就会忘记使用了哪个构造函数。@纳瓦兹:既然你提到了继承中的初始化顺序,那么提及虚拟基类和初始化顺序是合适的。你说的“在现代编译器上”是什么意思?我使用C++,因为至少TC3.0和我不记得编译器初始化初始化错误。
class Connection {

   boost::asio::tcp::ip::socket _socket;
   boost::asio::io_service _io_service;

   Connection() : _io_service(), _socket(_io_service)
   {
   }
};