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) {}