Effective C++筆記:使用noncopyable禁止類的拷貝
如果某些事物是獨一無二的,那么其相應(yīng)的類就應(yīng)該禁止拷貝,也就是要使類的copy構(gòu)造函數(shù)和copy assignment操作符不起作用。比如說,地球就是獨一無二的,那么可以這么定義地球:
class?Earth?{ public: ??......//member函數(shù)或friend函數(shù) private: ??Earth(const?Earth&);//只聲明 ??Earth&?operator=(const?Earth&);//只聲明 };
? ? ? ?有了上述class 定義,當客戶企圖拷貝Earth對象,編譯器會阻撓他。如果你不慎在member函數(shù)或friend函數(shù)之內(nèi)那么做,輪到連接器發(fā)出抱怨。但是一種更好的做法是將連接期錯誤移至編譯期,畢竟愈早偵測出錯誤愈好。此時可以專門設(shè)計一個阻止copying動作的base class,如下所示:
class?noncopyable { protected: ??noncopyable()?{} ??~noncopyable()?{} private://?emphasize?the?following?members?are?private ??noncopyable(?const?noncopyable&?); ??noncopyable&?operator=(?const?noncopyable&?); };
? ? ? ?對于構(gòu)造函數(shù)為什么聲明成protected呢?首先肯定不能為private,不然無法構(gòu)造子類實例。如果為public,那么外部是可以創(chuàng)建noncopyable這么一個實例的,可是這個實例是完全沒有意義的,該類只有在被繼承之后才有意義。所以此處聲明為protected是非常恰當合適的,既保證外部無法直接構(gòu)造一個無意義的noncopyable實例,又不影響構(gòu)造子類實例。
? ? ? ?現(xiàn)在,為了阻止Earth對象被拷貝,我們唯一需要做的就是繼承Uncopyable。當然,此時Earth內(nèi)部不需要再聲明copy構(gòu)造函數(shù)和copy assignment操作符了。
class?Earth:private?noncopyable { ??...... };