如果你给一个类提供了复制构造函数和operator=的重载实现,那么当你给这个类增加一个成员的时候,复制对象时新加的成员会被忽略,因为你已经给出了复制构造函数和operator=的重载实现,那么编译器就不会给出缺省的版本。遗憾的是,在这种情况下,编译器通常也不会报错。
还有一种情况就是给一个子类编写复制构造函数时,很容易忘记了对于子类中基类部分的成员变量的初始化(因为没有在子类中显式写出)。
所以,当你承担起“为子类撰写复制构造函数”的重大责任时,就必须确保该被初始化的变量能被正确初始化(尤其是基类部分),而且这部分往往是private的,所以应该让子类的复制构造函数调用相应的父类的函数,代码示例:
derived::derived(const derived& rhs): base(rhs), val(rhs.val){
...
}
derived& derived::operator=(const derived& rhs){
...
base::operator=(rhs);
val = rhs.val;
return *this;
}
有一个忠告是:让复制构造函数和operator=操作各自实现,不要互相调用(以图省事)。
如果确实想消除这两部分的重复代码,可以将相应操作放在另一个函数内(一般命名为init()),
总结:复制构造函数应该确保复制“对象内的所有成员变量”和“所有基类部分”(尤其是增加成员变量的时候要记得改写相应的复制构造函数)