对于拷贝构造函数和拷贝赋值函数,如果决定自己定义,那么不要忘记调用父类的相应构造函数。因为如果没有调用,对于拷贝构造函数,编译器会去自动调用父类的default构造函数,那么父类的成员没有被成功从子类实例拷贝;对于拷贝赋值函数,编译器不会做额外的操作,意味着只有子类的部分被赋值,而父类的成员维持原状。
如下代码子类中的拷贝构造函数和拷贝赋值函数,没有主动调用父类的相应函数:
class Base {
public:
Base():i(1) {
cout << "Base default constructor." << endl;
}
Base(int value):i(value){
cout << "Base constructor" << endl;
}
Base(const Base& base):i(base.i) {
cout << "Base copy constructor." << endl;
}
Base& operator=(const Base& base) {
cout << "Base operator =" << endl;
i = base.i;
return *this;
}
public:
int geti() {
return i;
}
void seti(int value) {
i = value;
}
private:
int i;
};
class Derived : public Base {
public:
Derived() : j(1) {
cout << "Derived default constructor." << endl;
}
Derived(int value) : j(value) {
cout << "Derived constructor." << endl;
}
Derived(const Derived& derived) :
// Base(derived),
j(derived.j){
cout << "Derived copy constructor." << endl;
}
Derived& operator=(const Derived& derived) {
cout << "Derived operator = " << endl;
// Base::operator=(derived);
j = derived.j;
return *this;
}
public:
int getj() {
return j;
}
void setj(int value) {
j = value;
}
private:
int j;
};
int main(int argc, char *args[])
{
Derived d;
d.seti(100);
cout << d.geti() << endl;
cout << d.getj() << endl;
Derived dd(d);
cout << dd.geti() << endl;
cout << dd.getj() << endl;
Derived ddd;
ddd = dd;
cout << ddd.geti() << endl;
cout << ddd.getj() << endl;
system("pause");
return 0;
}
运行结果如下:
Base default constructor.
Derived default constructor.
100
1
Base default constructor.
Derived copy constructor.
1
1
Base default constructor.
Derived default constructor.
Derived operator =
1
1
可见Base的变量i没有得到复制。
将两行注释删去,运行结果如下:
Base default constructor.
Derived default constructor.
100
1
Base copy constructor.
Derived copy constructor.
100
1
Base default constructor.
Derived default constructor.
Derived operator =
Base operator =
100
1
可以看到bb对象在构造时,Base的拷贝构造函数得到了调用,于是Base类的变量i成功复制成100;bbb对象在赋值的时候,Base类的Operator=得到了调用,于是Base的成员i赋值成了100.