首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类组件初始化顺序

类组件初始化顺序
EN

Stack Overflow用户
提问于 2011-06-29 02:08:10
回答 3查看 590关注 0票数 12
代码语言:javascript
复制
class D: A
{
    B obj;
    C obj2;
}

这里的建筑顺序是什么?

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

我知道您可以有一个显式的初始化列表:

代码语言:javascript
复制
D(): A(), B(), C()
{}

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

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-29 02:32:50

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

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

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

-然后,直接基类将按声明顺序初始化,就像它们出现在基类说明符列表中一样(不管mem初始化器的顺序如何)。

-然后,非静态数据成员应按照类定义中声明的顺序进行初始化(同样,无论mem-initializer的顺序如何)。

-最后,执行构造函数的主体。

注意:声明顺序的任务是确保以初始化的相反顺序销毁基和子对象。

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

票数 10
EN

Stack Overflow用户

发布于 2011-06-29 02:24:21

,但是这个初始化列表决定了初始化的顺序吗?

No..初始化-列表不确定成员数据和基子对象的初始化顺序。成员是按照声明的顺序初始化的,基次对象是按照它们的提及顺序构造的--从左到右:

代码语言:javascript
复制
struct A : B, C {}  //B is constructed before C

同时,在初始化成员数据之前构造基本子对象。

代码语言:javascript
复制
struct A : B, C 
{
      D d;
      E e;
};

上述结构的初始化顺序:

代码语言:javascript
复制
    B     =>    C      =>   d    =>   e   
subobject   subobject     member    member

然后它们被按相反的顺序摧毁。

票数 10
EN

Stack Overflow用户

发布于 2011-06-29 02:27:27

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

如果我像这样定义了一个类:

代码语言:javascript
复制
class Connection {

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

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

这将在所有现代编译器中失败。因为_socket首先被定义为类成员,因此初始化列表将尝试首先初始化它,尽管初始化列表要求编译器首先初始化_io_service。但是,由于_io_service尚未初始化(套接字构造函数依赖于初始化的_io_service),_socket的初始化将导致分段错误。

也许有人可以引用标准的适当部分来说明这种行为。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6515042

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档