具有对象作为参数的构造函数

时间:2016-10-19 17:54:24

标签: c++ class c++11 constructor copy-constructor

假设我有一个课程如下:

<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会调用隐式定义的复制构造函数。

注意:为简洁起见,我已将私人,公共等排除在外。

2 个答案:

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