展示網(wǎng)站多少錢一個(gè)網(wǎng)站熱度查詢
在C++的類中,有四類特殊的成員函數(shù):① 默認(rèn)構(gòu)造函數(shù);② 拷貝構(gòu)造函數(shù);③ 拷貝賦值函數(shù)(operator=);④ 析構(gòu)函數(shù);它們控制著類的實(shí)例的創(chuàng)建、初始化、拷貝以及銷毀。
(1)默認(rèn)構(gòu)造函數(shù):如果對構(gòu)造函數(shù)進(jìn)行了重載,則編譯器不會隱式的生成一個(gè)默認(rèn)的構(gòu)造函數(shù),此時(shí)如果調(diào)用了默認(rèn)構(gòu)造函數(shù)會在編譯時(shí)報(bào)錯(cuò),為了避免這種情況,一般會選擇重寫默認(rèn)構(gòu)造函數(shù),且函數(shù)體為空。關(guān)鍵字 =default 優(yōu)化了這種行為,用該關(guān)鍵字標(biāo)記重寫的默認(rèn)拷貝構(gòu)造函數(shù),編譯器會隱式生成一個(gè)版本,在代碼更加簡潔的同時(shí),編譯器隱式生成的版本的執(zhí)行效率更高。
class Mine
{
public:// 重載構(gòu)造函數(shù),此時(shí)不會隱式生成默認(rèn)構(gòu)造函數(shù) Mine(int num) {}// 可選擇重寫默認(rèn)構(gòu)造函數(shù) Mine() {}// 關(guān)鍵字 =default 標(biāo)記編譯器隱式生成該類的默認(rèn)構(gòu)造函數(shù),// 代碼更簡潔,且隱式生成的版本執(zhí)行效率更高 Mine() = default;
};int main()
{// 調(diào)用默認(rèn)構(gòu)造函數(shù) Mine ob; // 調(diào)用默認(rèn)拷貝構(gòu)造函數(shù) Mine pOb(ob); // 需要特別注意的是:因?yàn)閠Ob是在創(chuàng)建時(shí)被賦值的,// 所以此處的賦值操作符調(diào)用的是默認(rèn)拷貝構(gòu)造函數(shù) Mine tOb = pOb;Mine sOb;// 在構(gòu)造完成之后,賦值操作符執(zhí)行的就是賦值運(yùn)算了,// 所以此時(shí)調(diào)用的就是拷貝賦值函數(shù) sOb = tOb;/** 離開作用域時(shí)自動調(diào)用默認(rèn)的析構(gòu)函數(shù) */return 0;
}
(2)拷貝構(gòu)造函數(shù)?和?拷貝賦值函數(shù):不論有沒有對它們進(jìn)行重載,編譯器始終會隱式生成默認(rèn)版本,但有的時(shí)候不希望類實(shí)例進(jìn)行拷貝構(gòu)造或拷貝賦值,此時(shí)可以重寫它們并將權(quán)限設(shè)置為private,但這樣只是利用語法特性來碰巧實(shí)現(xiàn)效果,且對友元會帶來困惑??梢允褂藐P(guān)鍵字 =delete 標(biāo)記不想被類實(shí)例調(diào)用的拷貝構(gòu)造和拷貝賦值,相當(dāng)于刪除了它們:
class Mine
{
public:// 保證重載了構(gòu)造函數(shù)后,編譯器會隱式生成一個(gè)默認(rèn)版本 Mine() = default;Mine(Mine& ob) = delete;Mine& operator=(Mine& ob) = delete;
};int main()
{Mine ob// 編譯錯(cuò)誤,調(diào)用的拷貝構(gòu)造函數(shù)已刪除 Mine pOb(ob);// 編譯錯(cuò)誤,調(diào)用的拷貝構(gòu)造函數(shù)已刪除 Mine tOb = pOb;Mine sOb;// 編譯錯(cuò)誤,調(diào)用的拷貝賦值函數(shù)已刪除 sOb = tOb;return 0;
}
(3)析構(gòu)函數(shù):一個(gè)類中有且僅有一個(gè)析構(gòu)函數(shù)(所以=delete不能用于析構(gòu)函數(shù)),它是一個(gè)無參無返回值且不能被重載的特殊成員函數(shù),由系統(tǒng)自動調(diào)用,析構(gòu)函數(shù)如果被重寫,則系統(tǒng)會調(diào)用重寫的版本,否則調(diào)用隱式生成的默認(rèn)版本:
class Mine
{
public:~Mine() {} // 顯示定義,相當(dāng)于重寫,若沒有,則調(diào)用編譯器默認(rèn)生成的版本 ~Mine(int) {} // 編譯錯(cuò)誤,析構(gòu)函數(shù)不允許被重載 ~Mine() = delete; // 編譯錯(cuò)誤,類僅有一個(gè)析構(gòu)函數(shù),刪除了析構(gòu)怎么銷毀對象
};