假设我有一个课程如下:
<span customDirectiveTranslation>{{translateble}}</span>
我有另一个B类,它有一个A类实例作为成员对象。
class A{
int x ;
A( int i ){
x = i ;
}
}
当我执行以下操作时:
class B{
int y ;
A obj_a ;
B( int j , A a ){
y = j ;
obj_a = a ;
}
}
第二行抛出一个错误,表示没有A :: A()形式的函数调用。我知道这意味着缺少默认样式构造函数,但为什么我需要它呢?使用定义的构造函数创建obj1,这不是问题。
我目前的想法是int main(){
A obj1( 1 ) ; // obj.x has value 1
B obj2( 2 , obj1 ) ;
}
和A a
会调用隐式定义的复制构造函数。
注意:为简洁起见,我已将私人,公共等排除在外。
答案 0 :(得分:3)
obj_a = a
调用operator=
,而不是复制构造函数。问题是,使用默认构造函数初始化obj_a
,因为您还没有指定在初始化列表中调用哪个构造函数。
B( int j , A a ) /*: obj_a{}*/ { /*...*/ }
^^^^^^^^^^^^^
implicit call to default constructor
你必须在成员初始化列表中用一个参数明确地调用构造函数:
B( int j , A a ) : obj_a{ a } { /*...*/ }
答案 1 :(得分:2)
当对象进入构造函数体时,它必须完全一致,所有成员都是构造的。所以在
B( int j , A a ){
y = j ;
obj_a = a ;
}
之前
{
y = j ;
obj_a = a ;
}
有机会做任何事情,obj_a
必须已经构建完毕。
由于Member Initializer List未提供有关如何构建obj_a
的说明,因此将使用类obj_a
的默认构造函数构建A
。类A
没有默认构造函数,没有A::A()
,因此引发了错误。
解决方案是使用Member Initializer List而不是在函数体内分配。这不仅可以节省构建快速写入的对象,编译器还有更多的优化方法,您可以获得其他一些小的改进。
班级B
应为:
class B{
int y ;
A obj_a ;
B( int j , A a ): y(j), obj_a(a)
{
}
}