以对象为参数的构造函数
Constructors with objects as parameters
假设我有一个class如下:
class A{
int x ;
A( int i ){
x = i ;
}
}
我还有另一个 class B,它有一个 class A 的实例作为成员对象。
class B{
int y ;
A obj_a ;
B( int j , A a ){
y = j ;
obj_a = a ;
}
}
当我执行以下操作时:
int main(){
A obj1( 1 ) ; // obj.x has value 1
B obj2( 2 , obj1 ) ;
}
第 2 行抛出一个错误,指出没有 A::A() 形式的函数调用。我知道这意味着缺少默认样式构造函数,但我为什么需要它? obj1 是使用定义的构造函数创建的,因此这不是问题。
我目前的想法是 A a
和 obj_a = a
将调用隐式定义的复制构造函数。
注意:为简洁起见,我已经排除了 private、public 等。
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 } { /*...*/ }
一个对象必须是完全一致的,在它进入构造函数的主体时,它的所有成员都已构造。所以在
B( int j , A a ){
y = j ;
obj_a = a ;
}
之前
{
y = j ;
obj_a = a ;
}
有机会做任何事情,obj_a
一定是建造好了。
由于 Member Initializer List 没有提供关于如何构建 obj_a
的说明,因此 obj_a
将使用 class [=16= 的默认构造函数构建]. Class A
没有默认构造函数,没有A::A()
,所以报错
解决方案是使用成员初始化器列表而不是在函数体内赋值。这不仅可以节省您构建一个将立即被覆盖的对象的时间,而且编译器还有更多的优化余地,您可能会得到一些其他的小改进。
Class B
应该是:
class B{
int y ;
A obj_a ;
B( int j , A a ): y(j), obj_a(a)
{
}
}
假设我有一个class如下:
class A{
int x ;
A( int i ){
x = i ;
}
}
我还有另一个 class B,它有一个 class A 的实例作为成员对象。
class B{
int y ;
A obj_a ;
B( int j , A a ){
y = j ;
obj_a = a ;
}
}
当我执行以下操作时:
int main(){
A obj1( 1 ) ; // obj.x has value 1
B obj2( 2 , obj1 ) ;
}
第 2 行抛出一个错误,指出没有 A::A() 形式的函数调用。我知道这意味着缺少默认样式构造函数,但我为什么需要它? obj1 是使用定义的构造函数创建的,因此这不是问题。
我目前的想法是 A a
和 obj_a = a
将调用隐式定义的复制构造函数。
注意:为简洁起见,我已经排除了 private、public 等。
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 } { /*...*/ }
一个对象必须是完全一致的,在它进入构造函数的主体时,它的所有成员都已构造。所以在
B( int j , A a ){
y = j ;
obj_a = a ;
}
之前
{
y = j ;
obj_a = a ;
}
有机会做任何事情,obj_a
一定是建造好了。
由于 Member Initializer List 没有提供关于如何构建 obj_a
的说明,因此 obj_a
将使用 class [=16= 的默认构造函数构建]. Class A
没有默认构造函数,没有A::A()
,所以报错
解决方案是使用成员初始化器列表而不是在函数体内赋值。这不仅可以节省您构建一个将立即被覆盖的对象的时间,而且编译器还有更多的优化余地,您可能会得到一些其他的小改进。
Class B
应该是:
class B{
int y ;
A obj_a ;
B( int j , A a ): y(j), obj_a(a)
{
}
}