为什么C ++拷贝构造函数会失败?

时间:2012-07-03 15:06:18

标签: c++

#include <iostream>
#include <string>

using namespace std;

class A
{
public:
    A() { i=1; j=2;};
    A (A &obj) { i= obj.i+100; j= obj.j+100;};
     int i;
     int j;
};

class B:public A
{
public:
    B():A() {i=10; j=20; k=30;};

    B(A &obj) {  A::A(obj); k=10000; };//

    int k;
};

int main()
{ 
    A dog;
    B mouse(dog);
    cout<<mouse.i<<endl;
    cout<<mouse.k<<endl;

    return 0;
}

我尝试为派生类编写一个复制构造函数,该构造函数利用了基类的复制构造函数。我希望mouse.i应该是101,但实际上编译结果是1. mouse.k的值是10000,这是预期的。我想知道我的代码有什么问题。

4 个答案:

答案 0 :(得分:5)

您必须使用初始化列表来调用父级的构造函数(您也应该为所有其他成员执行此操作):

B(A const& obj) : A(obj), k(10000) {}

此外,在复制时不要修改原始对象,因此您应该对其进行const引用。这将允许您从常量对象(或通过常量引用)复制,从而提高const正确性。

答案 1 :(得分:5)

在这个构造函数中:

B(A &obj) {  A::A(obj); k=10000; };

A::A(obj);不初始化基础子对象;相反,它创建了一个名为obj的本地对象。它相当于A::A obj;,与A obj;等效。 [更新:或者可能它做了别的事情,或者可能它是不正确的 - 无论如何,这是错误的。]

您想使用初始化列表:

B(A & obj) : A(obj), k(10000) {}

此外,您几乎肯定希望构造函数参数为A const &,以允许构造来自常量对象或临时对象。

答案 2 :(得分:4)

您应该像这样初始化基类:

B(A &obj):A(obj) {  k=10000; }

What are the rules for calling the superclass constructor?上有更多内容)。并注意:使用const复制构造函数参数:

A (const A &obj) {...}

修改

初始化实例成员的首选方法是通过初始化列表,因此您的ctor看起来像

B(A &obj):A(obj), k(10000) { }

答案 3 :(得分:0)

#include <iostream>
#include <string>

using namespace std;

class A
{
public:
A()
{
    i=1;
    j=2;
}

A (A &obj)
{
    i= obj.i+100;
    j= obj.j+100;
}

 int i;
 int j;
};

class B:public A
{
public:
B():A() {i=10; j=20; k=30;}

B(A &obj)
:A(obj)
 {
  //A::A(obj);
  k=10000;
  }//

int k;
};

int main()
{
    A dog;
    B mouse(dog);
    cout<<mouse.i<<endl;
    cout<<mouse.k<<endl;

    return 0;
}

这项工作对我来说

B(A &obj)
{
    A::A(obj)
}

在gcc编译器上是非法的