- 以下程序的输出为:
class Base
{
public:
Base(int val = 0):m_x(val){cout<<__FUNCTION__<<1<<endl;}
Base(const Base& oth):m_x(oth.m_x){cout<<__FUNCTION__<<2<<endl;}
int m_x = -1;
};
class Derived:public Base
{
public:
Derived(int val):Base(val), m_y(val){cout<<__FUNCTION__<<3<<endl;}
Derived(const Derived& oth):m_y(oth.m_y){cout<<__FUNCTION__<<4<<endl;}
int m_y;
};
int main()
{
Derived d1(10);
Derived d2 = d1;
cout<<d2.m_x << " " << d2.m_y << endl;
return 0;
}
输出为:
Base::Base1
Derived::Derived3
Base::Base1
Derived::Derived4
0 10
子类的构造函数因为没有显示的在初始化序列化表里调用父类的拷贝构造函数,编译器默认就调用父类的没有参数的构造函数,即调用父类的Base(int val = 0);
类derived展现了一个在所有c++环境下都会产生的bug:当derived的拷贝创建时,没有拷贝其基类部分。当然,这个derived对象的base部分还是创建了,但它是用base的缺省构造函数创建的,成员x被初始化为0(缺省构造函数的缺省参数值),而没有顾及被拷贝的对象的x值是多少!
为避免这个问题,derived的拷贝构造函数必须保证调用的是base的拷贝构造函数而不是base的缺省构造函数。这很容易做,只要在derived的拷贝构造函数的成员初始化列表里对base指定一个初始化值:
class Base
{
public:
Base(int val = 0):m_x(val){cout<<__FUNCTION__<<1<<endl;}
Base(const Base& oth):m_x(oth.m_x){cout<<__FUNCTION__<<2<<endl;}
int m_x = -1;
};
class Derived:public Base
{
public:
Derived(int val):Base(val), m_y(val){cout<<__FUNCTION__<<3<<endl;}
//Derived(const Derived& oth):Base(oth), m_y(oth.m_y){cout<<__FUNCTION__<<4<<endl;}
Derived(const Derived& oth):Base(oth.m_x), m_y(oth.m_y){cout<<__FUNCTION__<<4<<endl;}
int m_y;
};
int main()
{
Derived d1(10);
Derived d2 = d1;
cout<<d2.m_x << " " << d2.m_y << endl;
return 0;
}
输出为:
Base::Base1
Derived::Derived3
Base::Base2或Base::Base1
Derived::Derived4
10 10
现在,当用一个已有的同类型的对象来拷贝创建一个derived对象时,它的base部分也将被拷贝了。