#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,这是预期的。我想知道我的代码有什么问题。
答案 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编译器上是非法的