Effective C++ 条款12:复制对象的所有部分

Copy all parts of an object

copy构造函数和copy assignment操作符对一个类型的实例进行了copying。即使不刻意去编写,编译器一样会尽力相助。当你不需要编译器的好心相助时,也许会得到它的报复。假设字定义一个类型,并且实现了自己的copy构造函数和copy assignment:

class X {
public:
    X() : _size(0) { }
    virtual ~X() { }
    X(const X& rhs);
    X& operator=(const X& rhs);
    int GetSize(void) const { return _size; }
private:
    int _size;
};


X::X(const X &rhs) {
    this->_size = rhs.GetSize();        
}

X& X::operator=(const X& rhs) {
    if (this == &rhs)
        return *this;
    this->_size = rhs.GetSize();
    return *this;
}


现在X类型实现了自己的copy构造函数和copy assignment操作符,但如果当X类型又多了一个成员变量的时候,再编译时候编译器不会提醒我们当前X类型并没有实现所谓的Copy all parts of an object。这往往是违背了Copying函数原则的事情。
又如果X还有其派生类型,那么派生类型又没有做到这些事,编译器也懒的想提醒你。


 

class XX : public X {
public:
    XX() : X(), _size2(0) { }
    ~XX() { } 
    XX(const XX& rhs);
    XX& operator=(const XX& rhs);
    int GetSize2(void) const { return _size2; }
private:
    int _size2;
};

XX::XX(const XX& rhs) {
    this->_size2 = rhs.GetSize2();
};

XX& XX::operator=(const XX& rhs) {
    if (this == &rhs)
        return *this;
    this->_size2 = rhs.GetSize2();
    return *this;
}


基类型X的成员变量没有得到copying动作,为了承担起这份责任,必须调用基类型的copy构造函数以几copy assignment操作符。

XX::XX(const XX& rhs) : X(rhs) {
    this->_size2 = rhs.GetSize2();
};

XX& XX::operator=(const XX& rhs) {
    if (this == &rhs)
        return *this;
    X::operator=(rhs);
    this->_size2 = rhs.GetSize2();
    return *this;
}


所谓的复制每一个部分已经很清楚了,复制每一个当前类型内的成员变量,并调用基类型提供的copying函数。给一个建议,最好不要在copy assignment操作符里调用copy构造函数,这不是什么省事的动作,等同于构造了已经存在的对象。同样反会来在copy构造函数里调用copy assignment操作符也一样很无聊,copy构造函数是构造一个新的对象,而copy assignment操作符则是用于已经被构造过的对象上。
copy assignment操作符调用copy构造函数

XX& XX::operator=(const XX& rhs) {
    if (this == &rhs)
        return *this;
    return XX(rhs);
}


 

copy构造函数调用copy assignment操作符
XX::XX(const XX& rhs) {
    const_cast<XX*>(this) = &XX::operator =(rhs);
}

 

需要记住的

l  要确保拷贝函数拷贝对象的所有的数据成员,及其基类的所有部分,不要有遗漏。

l  不要尝试去实现一个拷贝函数来供其它的拷贝函数调用。取而代之的是,把公共部分放入一个“第三方函数”中共所有拷贝函数调用。

 

你可能感兴趣的:(C++,object,Class,编译器)