2.构造、析构、赋值运算

Constructors,Destructors,and Assignment Operators #

5.Know what functions C++ silently writes and calls #

  • 编译器可以暗自为class创建default构造函数 、copy构造函数、copy assignment操作符,以及析构函数

    区分copy构造和copy赋值

    class Widget{
    public:
        Widget();//default构造
        Widget(const Widget& rhs);//copy构造
        Widget& operator=(const Widget& rhs);//copy assignment操作符
    };
    Widget w1;//default构造
    Widget w2(w1);//copy构造
    w1 = w2;//copy assignment操作符
    Widget w3 = w2;//copy构造     通过是否真正产生新的对象来区分copy构造和拷贝赋值
    

6.Explicitly disallow the use of compiler-generated functions you do not want #

  • 所有编译器产出的函数都是public,为驳回编译器自动提供的机能,可将相应的成员函数声明为Private并且不予实现

    #define Q_DISABLE_COPY(Class) \
    		Class(const Class &) = delete;\
    		Class &operator=(const Class &) = delete;
    
    class Uncopyable
    {
    protected://允许derived对象构造和析构
        Uncopyable(){}
        ~Uncopyable(){}
    private:
        Uncopyable(const Uncopyable&);
        Uncopyable& operator=(const Uncopyable&);
    }
    //继承Uncopyable可以阻止HomeForSale对象被拷贝
    class HomeForSale:private Uncopyable
    {
        ...
    }
    

7.Declare destructors virtual in polymorphic base classes #

  • 只有当class内含至少一个virtual函数才为它声明virtual析构函数

  • 标准string和STL窗口都不被设计作为base classed使用,因为它们的析构函数都不带virtual

8.Prevent exceptions from leaving destructors #

  • 析构函数绝对不能抛出异常

  • 通常通过调用abort结束程序,来阻止异常从析构函数传播出去

DBConn::~DBCOnn()
{
    try{
        db.close();//可能抛出异常
    }
    catch(...){
        std::abort();
    }
}

9.Never call virtual functions during construction or destruction #

禁止在构造函数和析构函数中调用virtual函数,并且在它们调用的所有函数也都服从这一约束,因为此时derived class的成员变量处于未定义的状态

class Transaction{
public:
    Transaction();
    virtual void logTransaction() const = 0;
}

Transaction::Transaction()
{
    ...
    logTransaction();//错误,构造和析构中禁止调用虚函数
}

class BuyTransaction:public Transaction{
public:
    virtual void logTransaction() const = 0;
}

10.Have assignment operators return a reference to *this #

让赋值assignment操作符返回一个reference to *this

class Widget{
public:
    Widget& operator+=(const Widget& rhs)
    {
        ...
        return *this;
    }
    Widget& operator=(int rhs)
    {
        ...
        return *this;        
    }
}

11.Handle assignment to self in operator= #

Widget& Widget::operator=(const Widget& rhs)
{
    if(this == &rhs)
        return *this;
    delete pb;
    pb = new Bitmap(*rhs.pb);
    return *this;
}

12.Copy all parts of an object #

Copying函数应该确保复制对象内的所有成员变量及所有base class成分

//调用所有base classes内的适当的copying函数
class PriorityCUstomer::PriorityCUstomer(const PriorityCustomer& rhs)
	:Customer(rhs),//调用base class的copy构造函数
	priority(rhs.priority)
{
}
//不该令copy assignment操作符调用copy构造函数,也不在copy构造函数调用copy assignment操作符
PriorityCUstomer& PriorityCUstomer::operator=(const PriorityCUstomer& rhs)
{
    Customer::operator=(rhs);//调用base class的赋值动作
    priority = rhs.priority;
    return *this;
}