假设我有一个类Alpha
,它有两个成员变量beta
和gamma
,它们分别是类Beta
和Gamma
的对象:
class Alpha
{
public:
Beta beta_;
Gamma gamma_;
};
现在,类Gamma
本身有一个成员变量p_beta
,它是指向beta
中相同Alpha
变量的指针。但是,Gamma
没有默认构造函数,而是必须通过传递p_beta
来构造:
class Gamma
{
public:
Beta* p_beta_;
Gamma(Beta* p_beta)
{
p_beta_ = p_beta;
}
};
那么,如果我想创建类alpha
的对象Alpha
,我需要在gamma_
的初始化列表中构建其成员Alpha
, Gamma
没有默认构造函数:
class Alpha
{
public:
Beta beta_;
Gamma gamma_;
Alpha() : gamma_(&beta_){}
};
我的问题是:在此初始值设定项列表中构建时beta_
之前是否已创建gamma_
?我原以为在创建任何其他成员变量之前调用初始化列表,在这种情况下beta_
将不存在。如果当时尚未创建beta_
,那么在构建beta_
时如何将指针传递给gamma_
?
答案 0 :(得分:3)
类的非静态非变量数据成员按声明顺序初始化,毫无例外。您没有为beta_
指定 mem-initializer 的事实只是意味着它将被默认初始化,并且此默认初始化发生在之前初始化gamma_
因为beta_
在声明顺序中位于gamma_
之前。
除此之外,即使您在类定义中更改了beta_
和gamma_
的顺序,传递指向尚未初始化的对象的指针也没有错。
答案 1 :(得分:2)
在此初始值设定项列表中构建
beta_
之前是否已创建gamma_
?
是的,beta_
将在gamma_
之前默认构建,因此使用其地址是安全的。非静态数据成员的初始化以声明顺序发生,并以反向声明顺序进行销毁。
答案 2 :(得分:0)
来自[class.base.init] / 13,强调我的:
在非委托构造函数中,初始化按以下顺序进行:
- 首先,只有最派生类(1.8)的构造函数,虚拟基类是...
- 然后,直接基类按声明顺序初始化...
- 然后,非静态数据成员按照在类定义中声明的顺序进行初始化 (无论 mem-initializers 的顺序如何)。
是的,beta_
将在gamma_
之前构建(初始化程序的顺序无关紧要)