class D: A
{
B obj;
C obj2;
}这里的建筑顺序是什么?
我知道D将在A、B和C之后被构造,但我真正想知道的是,A是否保证在B或C之前被构造,甚至是否保证B在C之前被构造。
我知道您可以有一个显式的初始化列表:
D(): A(), B(), C()
{}但是,初始化列表决定了初始化的顺序吗?
另外,是否有任何组件具有默认构造函数?
发布于 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。初始化程序列表的顺序是无关的,比如是否有任何成员有或没有默认构造函数--如果一个成员没有默认构造函数,并且它没有在初始化程序列表中显式初始化,那么它就有一个未指定的值。
发布于 2011-06-29 02:24:21
,但是这个初始化列表决定了初始化的顺序吗?
No..初始化-列表不确定成员数据和基子对象的初始化顺序。成员是按照声明的顺序初始化的,基次对象是按照它们的提及顺序构造的--从左到右:
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然后它们被按相反的顺序摧毁。
发布于 2011-06-29 02:27:27
也许这个破译的代码示例将有助于说明:
如果我像这样定义了一个类:
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的初始化将导致分段错误。
也许有人可以引用标准的适当部分来说明这种行为。
对于问题的后半部分,基类总是在类自己的成员之前初始化。
https://stackoverflow.com/questions/6515042
复制相似问题