在默认构造函数之前或之后调用初始化程序列表吗?

时间:2015-05-08 19:22:24

标签: c++

假设我有一个类Alpha,它有两个成员变量betagamma,它们分别是类BetaGamma的对象:

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_的初始化列表中构建其成员AlphaGamma没有默认构造函数:

class Alpha
{
public:
    Beta beta_;
    Gamma gamma_;
    Alpha() : gamma_(&beta_){}
};

我的问题是:在此初始值设定项列表中构建时beta_之前是否已创建gamma_?我原以为在创建任何其他成员变量之前调用初始化列表,在这种情况下beta_将不存在。如果当时尚未创建beta_,那么在构建beta_时如何将指针传递给gamma_

3 个答案:

答案 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_之前构建(初始化程序的顺序无关紧要)