构造/析构/赋值运算

条款05:了解C++默默编写并调用哪些函数

  如果我们写了一个空类:

class Empty { };

  编译器会为这个类添加一些default的函数,相当于:

class Empty {
public:
    Empty() { ... }                                //default构造函数                  
    Empty(const Empty& rhs) { ... }                //copy构造函数
    ~Empty() { ... }                               //析构函数
    Empty & operator=(const Empty& rhs) { ... }    //copy assigment操作符
}; 

  其中,编译器创建的copy构造函数和copy assigment操作符只是单纯地将来源对象的每一个non-static成员变量拷贝到目标变量。编译器创建的copy assigment操作符与copy构造函数行为上基本相同,但一般只有生成的代码合法而且有适当机会证明它有意义时,编译器才会创建copy assigment操作符。例如类中有const或者引用的字段时,往往编译器会拒绝创建copy assigment操作符。

  如果我们为类声明了构造函数,则编译器不再给类添加default构造函数。

条款6:若不想使用编译器自动生成的函数,就应该明确拒绝

  如果不想使用default构造函数和析构函数,我们可以通过声明构造函数和析构函数来拒绝。

  但是如果不想使用copy构造函数和copy assigment操作符,例如,我们不允许一下操作:

Object a1;
Object a2;
Object a3(a1);     //不允许该操作
Object a2 = a1;    //不允许该操作

  如何才能拒绝上面两种情况呢?

  一种方法是将copy构造函数和copy assigment操作符声明为private,这样外部就无法调用到这两个方法,编译器也不会自己添加。但是用户member函数或friend函数还是有可能调用到这两个方法,所以我们可以只声明这两个方法而不实现,如果不慎调用到,会获得一个连接错误(Link Error)。

  另一种方法甚至可以将可能的连接错误提前到编译期,做法定义一个Uncopyable的基类,这个类中按上一种方法声明,而其他的想阻止对象copy的类只需要继承该基类就可以了:

class Uncopyable {
protect:
    Uncopyable () {}
    ~Uncopyable () {}
private:
    Uncopyable(const Uncopyable&);
    Uncopyable& operator=(const Uncopyable&);
};

//其他类只需要继承Uncopyable即可
class NewClass : private Uncopyable {
    ...
};

条款7:为多态基类声明virtual析构函数

条款8:别让异常逃出析构函数

条款9:绝不要在构造函数中调用virtual函数

条款10:令operator=返回一个reference to *this 

  可以实现连锁复制,如 a = b = c;

  这个条款同样适用于 operator+=,-=,*=,/=等等。

条款11:在operator=中处理“自我赋值”

  例如:

Widget& Widget::operator=(const Widghet& rhs) {
    if (this == &rhs)
        return *this;
    ...
    return *this;
}

  另外一种处理自我赋值的方法:

//copy and swap
Widget& Widget::operator=(const Widghet& rhs) {
    Widget tem(rhs);
    swap(temp);
    return *this;
}

条款12:复制对象时勿忘其每一个成分

  必须确保:1.复制所有local成员变量;2.调用所有base classes内适当的copying函数。

原文地址:https://www.cnblogs.com/yitong0768/p/4562189.html