Effective Modern C++ 學(xué)習(xí)筆記4——特種成員函數(shù)

C++中有6種特殊的成員函數(shù):默認(rèn)構(gòu)造函數(shù)、析構(gòu)函數(shù)锯仪、復(fù)制構(gòu)造函數(shù)泵督、復(fù)制賦值運算符、移動構(gòu)造函數(shù)庶喜、移動賦值運算符小腊。

這些成員函數(shù)在一些情況下會由編譯器自動生成,并且都是public的久窟。那么秩冈,哪些情況會阻礙這些成員函數(shù)的生成呢?

幾個例子

案例1

下面的代碼能否編譯通過斥扛?

class NoCopy {
public:
    NoCopy() = default;
    NoCopy(NoCopy&& rhs) = default; // 移動構(gòu)造函數(shù)
};

int main() {
    NoCopy a;
    NoCopy b(a); // ERROR
}

答案是不能入问,編譯器給出的錯誤是:

error: use of deleted function 'constexpr NoCopy::NoCopy(const NoCopy&)

意思是說,NoCopy類沒有復(fù)制構(gòu)造函數(shù)稀颁,所以不能用a來初始化b芬失。

如果刪掉移動構(gòu)造函數(shù)的聲明,則代碼可以正常編譯峻村。

這是為什么麸折?其實就是因為,移動構(gòu)造函數(shù)的聲明會導(dǎo)致編譯期不會隱式生成復(fù)制構(gòu)造函數(shù)粘昨。

案例2

我們再看一個例子垢啼,下面這個代碼窜锯,調(diào)用的是移動構(gòu)造函數(shù),還是復(fù)制構(gòu)造函數(shù)芭析?

class NoMove {
public:
    NoMove() = default;
    virtual ~NoMove() = default; // 顯式聲明析構(gòu)函數(shù)
private:
    std::string s;
};

int main() {
    NoMove a;
    NoMove b(std::move(a)); // 能否調(diào)用移動構(gòu)造函數(shù)锚扎?
}

答案是,調(diào)用的是復(fù)制構(gòu)造函數(shù)馁启。原因和上例差不多驾孔,這里是因為顯式聲明了析構(gòu)函數(shù),導(dǎo)致不會隱式生成移動構(gòu)造函數(shù)惯疙。在需要移動構(gòu)造函數(shù)時翠勉,會使用復(fù)制構(gòu)造函數(shù)來代替。

你可能會想霉颠,反正都是編譯器自動生成的对碌,有必要區(qū)分嗎?

是的蒿偎,有必要朽们,這決定了會調(diào)用其成員變量s的移動構(gòu)造函數(shù)還是復(fù)制構(gòu)造函數(shù)。

自動生成規(guī)則

看了上面的例子诉位,會有個疑問骑脱,特種成員函數(shù)在什么情況下不會自動生成呢?

默認(rèn)構(gòu)造函數(shù)大家應(yīng)該都知道苍糠,只有沒有聲明任何構(gòu)造函數(shù)的情況下才會生成叁丧。

其他5個成員函數(shù)的生成更加復(fù)雜,它們之間會相互影響椿息。

如圖歹袁,紅色箭頭代表顯示聲明一個成員函數(shù)會導(dǎo)致另一個成員函數(shù)不會自動生成;綠色代表沒有影響:

為什么會有如此復(fù)雜的關(guān)系寝优?一方面是考慮“大三律”的思想条舔,另一方面是為了兼容C++98的代碼。

大三律

大三律是說:如果你聲明了復(fù)制構(gòu)造函數(shù)乏矾、賦值運算符孟抗,或析構(gòu)函數(shù)中的任意一個,你就得同時聲明所有這三個钻心。

為什么凄硼?其實很簡單,之所以顯示聲明捷沸,就是因為默認(rèn)的函數(shù)不適用摊沉,很可能說明其中包含了資源管理,例如new痒给、delete说墨。而這樣的操作一定要在這三個函數(shù)中都進行處理才正確骏全。

事實上,兩種移動操作也是同理尼斧。綜合起來姜贡,在C++11中就應(yīng)該是“大五律”了。

在C++11標(biāo)準(zhǔn)中棺棵,已經(jīng)將上圖綠色的箭頭變成deprecate了楼咳,也就是說,在將來的C++版本中烛恤,可能任意聲明這5個成員函數(shù)中的一個母怜,就不會自動生成其他幾個成員函數(shù)了。但當(dāng)前版本為了兼容C++98代碼棒动,還暫時保留圖中的綠色箭頭糙申。

使用建議

之前有提到過宾添,析構(gòu)函數(shù)最好聲明為virtual的船惨。但結(jié)合今天的例子,這又會導(dǎo)致無法自動生成兩個移動成員函數(shù)缕陕。

即使一個類現(xiàn)在沒有顯式聲明析構(gòu)函數(shù)粱锐,如果將來有一天想在析構(gòu)函數(shù)中加個日志,聲明了它扛邑,這就會導(dǎo)致原本自動生成的移動構(gòu)造函數(shù)被刪除怜浅,移動操作都變成了復(fù)制操作,可能會大幅影響性能蔬崩,僅僅是因為聲明了一個析構(gòu)函數(shù)恶座。

所以,比較穩(wěn)妥的辦法是沥阳,如果這個類可能會復(fù)制或移動跨琳,那就把兩個復(fù)制、兩個移動桐罕,以及析構(gòu)函數(shù)全都聲明脉让。如果沒有特別的需求,可以直接使用默認(rèn)實現(xiàn) =default

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末功炮,一起剝皮案震驚了整個濱河市溅潜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌薪伏,老刑警劉巖滚澜,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫁怀,居然都是意外死亡设捐,警方通過查閱死者的電腦和手機潦牛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挡育,“玉大人巴碗,你說我怎么就攤上這事〖春” “怎么了橡淆?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長母赵。 經(jīng)常有香客問我逸爵,道長,這世上最難降的妖魔是什么凹嘲? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任师倔,我火速辦了婚禮,結(jié)果婚禮上周蹭,老公的妹妹穿的比我還像新娘趋艘。我一直安慰自己,他們只是感情好凶朗,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布瓷胧。 她就那樣靜靜地躺著,像睡著了一般棚愤。 火紅的嫁衣襯著肌膚如雪搓萧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天宛畦,我揣著相機與錄音瘸洛,去河邊找鬼。 笑死次和,一個胖子當(dāng)著我的面吹牛反肋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斯够,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼囚玫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了读规?” 一聲冷哼從身側(cè)響起抓督,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎束亏,沒想到半個月后铃在,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年定铜,在試婚紗的時候發(fā)現(xiàn)自己被綠了阳液。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡揣炕,死狀恐怖帘皿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情畸陡,我是刑警寧澤鹰溜,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站丁恭,受9級特大地震影響曹动,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牲览,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一墓陈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧第献,春花似錦贡必、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至岔绸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橡伞,已是汗流浹背盒揉。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兑徘,地道東北人刚盈。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像挂脑,于是被迫代替她去往敵國和親藕漱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容