C++ 初始化订单问题

C++ 初始化订单问题,c++,initialization,initialization-order,C++,Initialization,Initialization Order,给定代码示例: class B { //Some contents. }; class C { private: B& b; }; class A { private: B b; C c; }; 类C有一个对a b的引用,因此需要用它初始化它。类A包含一个B实例和一个C实例 我的问题是:我可以在A中初始化C实例,在A中初始化B实例吗(假设我费心把构造函数放进去)?其次,我是否需要在A中执行B的任何显式初始化,或

给定代码示例:

class B {
    //Some contents.
};

class C {
    private:
        B& b;
};

class A {
    private:
        B b;
        C c;
};
类C有一个对a b的引用,因此需要用它初始化它。类A包含一个B实例和一个C实例


我的问题是:我可以在A中初始化C实例,在A中初始化B实例吗(假设我费心把构造函数放进去)?其次,我是否需要在A中执行B的任何显式初始化,或者它是默认初始化的,因为它是类中的A类类型?

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


当您创建A的实例时,A中的B和C都会自动实例化/构造。

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

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

不,您不必显式初始化
b
(除非是),除非您不希望它是默认构造的。所以这个代码就是您想要的(同样,如果
B
不是POD):


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

C::C(B& bInst): b(bInst){}
A::A():b(), c(b) {}
当然,如果
C
的构造函数实际使用
b
(而不仅仅是其地址),则需要确保初始化顺序保持不变,因此
b
必须在
C
之前声明,因为成员是按照声明顺序初始化的(即使初始化列表将它们按不同的顺序排列)

不,您不需要显式初始化B,因为如果不这样做,它将是默认构造的。当然,如果B是一个POD,这意味着它将保持未初始化状态(而使用
a()
的初始化器列表中的
B()
显式初始化它会将其初始化为
0

我可以用A中的B实例初始化A中的C实例吗(假设我费心把构造函数放进去)

当然

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


不,没关系。

引用与此有什么关系?如果C包含实际的B而不是对a B的引用,C.B和B将是B的单独实例,不可能是同一个。不管怎样,他想将一个从另一个初始化。这完全不相关。不,您不需要显式初始化B,因为如果不初始化,它将是默认构造的"只有当它不是POD时,它才会默认构造;也就是说,它很可能保持未初始化状态。@ildjarn:是的,但让它保持未初始化状态就是我所说的默认构造POD。不过,我会更改我的答案以反映这一点。如果使用一个尚未初始化的变量,它就是UB,即使它是POD。对于instance,
intx;请注意,即使您在
b
内部
A
之前声明
c
,这也会起作用。使用
b
内部
c
的构造函数的结果是未定义的,尽管!@RicardoCárdenes啊,是的,谢谢,我添加了一个关于这一点的注释。
C::C(B& bInst): b(bInst){}
A::A():b(), c(b) {}