给定代码示例:
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执行任何显式初始化吗?还是因为它是类中的类类型而默认初始化?
成员变量按照它们在类声明中声明的顺序进行初始化(即使您在构造函数的初始化列表中有不同的顺序),所以是的,在初始化c
时,b
将被初始化,您可以使用b
来初始化c
。
正如Ricardo Cardenes所指出的,即使在类定义中在b
之前声明c
(这意味着您将向C::C
传递对未初始化的B
的引用),它仍然可以工作,但是如果在C::C
中使用对象,则会导致未定义的行为。首先声明b
更安全,因为尽管现在可能不会在C::C
中使用b
,但将来可能会忘记引用引用了未初始化的B
,从而导致UB。
不,您不必显式初始化b
(除非它是POD),除非您不希望它是默认构造的。所以这个代码就是你想要的(同样,如果B
不是POD):
A::A() : c(b) { }
对于您的第一个问题:您可以通过编写以下构造函数来初始化它:
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的引用,而不是单独的实例,所以可以在C中放入构造函数,让a.C.B引用a.B.
当您创建A的实例时,A中的B和C都会自动实例化/构造。