三/五法則
??需要析構函數(shù)的類也需要拷貝和賦值操作
??如果這個類需要一個析構函數(shù)侥锦,我們幾乎可以肯定它也需要一個拷貝構造函數(shù)和一個拷貝賦值運算符帮孔。
??需要拷貝操作的類也需要賦值操作香浩,反之亦然
??某些類所要完成的工作类缤,只需要拷貝和賦值操作,不需要析構函數(shù)邻吭。一個類需要一個拷貝賦值運算符餐弱,幾乎可以肯定它也需要一個拷貝構造函數(shù)。
使用=default
??我們可以通過將拷貝控制成員定義為=default來顯式地要求編譯器生成合成的版本:
class Sales_data {
public:
//拷貝控制成員囱晴;使用default
Sales_data()=default;
Sales_data(constr Sales_data&)=default;
Sales_data& operator=(const Sales_data &);
~Sales_data()=default;
//其他成員的定義膏蚓,如前
};
Sales_data& Sales_data::operator=(const Sales_data&)=default;
??當我們在類內(nèi)用=default修飾成員的聲明時,合成的函數(shù)將隱式地聲明為內(nèi)聯(lián)的畸写,如果我們不希望合成的成員是內(nèi)聯(lián)函數(shù)驮瞧,應該只對類外定義使用=default。
阻止拷貝
??有些情況下枯芬,我們想要阻止或者改變類的拷貝论笔。
??定義刪除的函數(shù)
??我們可以通過將拷貝構造函數(shù)和拷貝賦值運算符定義為刪除的函數(shù)來阻止拷貝。刪除函數(shù)是這樣一種函數(shù):我們雖然聲明了它們千所,但不能以任何方式使用它們狂魔。在函數(shù)的參數(shù)列表后面加上=delete來指出我們希望將它定義為刪除的:
struct NoCopy {
NoCopy()=default; //使用合成的默認構造函數(shù)
NoCopy(const NoCopy&)=delete; //阻止拷貝
//....
};
??與=default不同,=delete必須出現(xiàn)在函數(shù)第一次聲明的時候真慢,我們可以對任何函數(shù)指定=delete毅臊,我們只能對編譯器可以合成的默認構造函數(shù)或拷貝控制成員使用=default。
??析構函數(shù)不能是刪除的成員
??我們不能刪除析構函數(shù)黑界,如果析構函數(shù)被刪除管嬉,就無法銷毀此類型的對象了,對于一個刪除了析構函數(shù)的類型朗鸠,編譯器將不允許定義該類型的變量或創(chuàng)建該類的臨時對象蚯撩。對于刪除了析構函數(shù)的類型,我們可以動態(tài)分配這種類型的對象烛占,但是不能釋放這些對象:
struct NoDtor {
NoDtor()=default; //使用合成默認構造函數(shù)
~NoDtor()=delete; //我們不能銷毀NoDtor類型的對象
}胎挎;
NoDtor nd; //錯誤:NoDtor的析構函數(shù)是刪除的
NoDtor *p=new NoDtor(); //正確:但我們不能delete p
delete p; //錯誤:NoDtor的析構函數(shù)是刪除的
??合成的拷貝控制成員可能是刪除的
??如果一個類為定義構造函數(shù)忆家,編譯器會為其合成一個默認構造函數(shù)犹菇,對某些類來說,編譯器將這些合成的成員定義為刪除的函數(shù)芽卿。如果一個類有數(shù)據(jù)成員不能默認構造揭芍、拷貝、復制或銷毀卸例,則對應的成員函數(shù)將被定義為刪除的称杨。
??private拷貝控制
??在新標準發(fā)布之前肌毅,類通過將其拷貝構造函數(shù)和拷貝賦值運算符聲明為private的來阻止拷貝。