C++之复制对象时勿忘每一个成分(12)---《Effective C++》

条款12:赋值对象时勿忘其每一个成分

C++中设计良好的对象系统会将对象的内部封装起来,只留下两个函数负责对象那个拷贝(赋值),即copy构造函数和copy operator=。
如果我们自己声明自己的copying函数,则C++的编译器则不会对我们自己提供的copying函数进行检验,即使copying函数出错了编译器并不会报错。
具体参看如下代码:

class A{
public:
    A(const A&);
    A& opreator=(const A&);
    ...
private:
    std::string A_a;
}
A::A(const A&a){
    this->A_a=a->A_a;
}
A& A::operator::=(const A& a){
    if(this==&a) return *this;
    this->A_a=a->A_a;
    return *this;
}

可是如果此时我们将A中加入新的变量呢?

class B{};
class A{
public:
    ...
private:
    std::string A_a;
    B b;
}

这时候,copying构造函数只是简单的复制了A_a,对于b成员变量并没有进行复制,大多数编译器无法检测出这些问题,因此,我们必须:
1)如果我们为类添加一个成员变量,必须同时修改copying函数,同时包括构造函数和一些非标准的operator=函数;

如果发生继承呢?

class A{
public:
    ...
    A(const A&a);
    A& operator=(const A&a);
private:
    std::string name;
}
class B:public A{
public:
    ...
    B(const B&b);
    B& operator=(const B&b);
private:
    int x;
}
B::B(const B&b):A(b){
    ...
}
B& B::operator=(const B&b){
    A::operator=(b);
    this->x=b.x;
    return *this;
}

2)可以发现对于继承体系中,当你编写子类的copying函数,请确保

  • 列表内容
  • 复制所有local成员变量 ,同时调用所有的base classes中适当的copying函数
    PS:注意此时不能用copy与构造函数调用copy assignment运算,同时copy assignment也不能调用copy构造函数,不合理,因为这样相当于试图调用一个已经存在的对象;
    总结:
    1)copying函数应该确保赋值“对象内的所有成员变量”和“所有基类成分”;
    2)不要尝试以某个copying函数实现另一个copying函数,应该共同放在第三个函数中,并有两个copying函数调用。

你可能感兴趣的:(C++)