初始化订单问题

时间:2012-01-10 18:57:23

标签: c++ initialization initialization-order

给出代码示例:

class B {
    //Some contents.
};

class C {
    private:
        B& b;
};

class A {
    private:
        B b;
        C c;
};

C类引用了b,因此需要用它进行初始化。 A类包含B的实例和C的实例。

我的问题是:我可以用A中的B实例初始化A中的C实例(假设我确实懒得把构造函数放入)?其次,我是否需要在A中执行B的任何显式初始化,还是默认初始化,因为它是类中的类类型?

4 个答案:

答案 0 :(得分:6)

成员变量按照它们在类声明中声明的顺序进行初始化(即使你在构造函数的初始化列表中有不同的顺序),所以是的,到时候c正在初始化,b将被初始化,您可以使用b初始化c

正如Ricardo Cardenes指出的那样,即使你在类定义中c之前声明b,它仍会有效(这意味着你会将C::C的引用传递给未初始化的{{1}但是,如果使用 B内的对象,则会导致未定义的行为。首先声明C::C会更安全,因为虽然您现在可能不会在b内使用b,但您可能在将来忘记该引用是指未初始化的C::C,并导致UB。

不,您不必明确初始化B(除非它是POD),除非您不希望它是默认构造的。所以这段代码就是你想要的(再次,如果b不是POD):

B

答案 1 :(得分:3)

关于第一个问题:您可以通过编写如下构造函数来初始化它:

C::C(B& bInst): b(bInst){}
A::A():b(), c(b) {}

当然,如果C的构造函数实际使用b(而不仅仅是其地址),则需要确保初始化顺序保持不变,因此必须声明bc之前,因为成员按照它们被声明的顺序初始化(即使初始化列表以不同的顺序放置它们)。

并且您不需要显式初始化B,因为如果不这样做,它将是默认构造的。当然,如果B是POD,这意味着保持未初始化(使用b()初始化列表中的A()明确初始化它会将其初始化为0

答案 2 :(得分:0)

是的,因为C只包含对B的引用而不是单独的实例,所以你可以在C中放置一个构造函数,让A.C.b引用A.B。

当您创建A的实例时,

A中的B和C都会自动实例化/构建。

答案 3 :(得分:0)

  

我可以使用A中的B实例初始化A中的C实例(假设我没有把构造函数放入其中)

不确定

  

其次,我是否需要在A中执行B的任何显式初始化,还是默认初始化,因为它是类中的类类型?

不,那很好。