官术网_书友最值得收藏!

1.6 final、override關(guān)鍵字和=default、=delete語法

final、override、=default、=delete是C++11新增的一組非常具有標記意義的關(guān)鍵字和語法,這里逐一介紹它們。

1.6.1 final關(guān)鍵字

final 關(guān)鍵字修飾一個類,這個類將不允許被繼承,這在其他語言(如 Java)中早就實現(xiàn)了。在 C++11中,final關(guān)鍵字要寫在類名的后面,這在其他語言中是寫在 class關(guān)鍵字前面的。示例如下:

由于類A被聲明成final,B繼承A,所以編譯器會報如下錯誤提示類A不能被繼承:

error C3246:'B':cannot inherit from'A'as it has been declared as'final'

1.6.2 override關(guān)鍵字

C++語法規(guī)定,在父類中加了virtual關(guān)鍵字的方法可以被子類重寫,子類重寫該方法時可以加或不加virtual關(guān)鍵字,例如下面這樣:

這種寬松的規(guī)定可能會帶來以下兩個問題。

◎ 當我們閱讀代碼時,無論子類重寫的方法是否添加了virtual關(guān)鍵字,我們都無法直觀地確定該方法是否是重寫的父類方法。

◎ 如果我們在子類中不小心寫錯了需要重寫的方法的函數(shù)簽名(可能是參數(shù)類型、個數(shù)或返回值類型),這個方法就會變成一個獨立的方法,這可能會違背我們重寫父類某個方法的初衷,而編譯器在編譯時并不會檢查到這個錯誤。

為了解決以上兩個問題,C++11引進了override關(guān)鍵字,其實override關(guān)鍵字并不是新語法,在 Java 等其他編程語言中早就支持。類方法被 override 關(guān)鍵字修飾,表明該方法重寫了父類的同名方法,加了該關(guān)鍵字后,編譯器會在編譯階段做相應的檢查,如果其父類不存在相同簽名格式的類方法,編譯器就會給出相應的錯誤提示。

情形一,父類不存在,子類標記了override的方法:

由于在父類A中沒有func方法,所以編譯器會提示錯誤:

情形二,父類存在,子類標記了override的方法,但函數(shù)簽名不一致:

這時編譯器會報同樣的錯誤。

正確的代碼如下:

1.6.3=default語法

如果一個 C++類沒有顯式給出構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、operator=這幾類函數(shù)的實現(xiàn),則在需要它們時,編譯器會自動生成;或者,在給出這些函數(shù)的聲明時,如果沒有給出其實現(xiàn),則編譯器在鏈接時會報錯。如果使用=default標記這類函數(shù),則編譯器會給出默認的實現(xiàn)。來看一個例子:

這樣的代碼是可以編譯通過的,因為編譯器默認生成 A 的一個無參構(gòu)造函數(shù),假設(shè)我們現(xiàn)在向A提供一個有參構(gòu)造函數(shù):

這時,編譯器就不會自動生成默認的無參構(gòu)造函數(shù)了,這段代碼會編譯出錯,提示A沒有合適的無參構(gòu)造函數(shù):

我們這時可以手動為A加上無參構(gòu)造函數(shù),也可以使用=default語法強行讓編譯器自己生成:

=default 最大的作用可能是在開發(fā)中簡化了構(gòu)造函數(shù)中沒有實際初始化代碼的寫法,尤其是聲明和實現(xiàn)分別屬于.h和.cpp文件。例如,對于類 A,其頭文件為 a.h,其實現(xiàn)文件為 a.cpp,則正常情況下我們需要在 a.cpp 文件中寫其構(gòu)造函數(shù)和析構(gòu)函數(shù)的實現(xiàn)(可能沒有實際的構(gòu)造和析構(gòu)邏輯):

可以發(fā)現(xiàn),即使在 A 的構(gòu)造函數(shù)和析構(gòu)函數(shù)中什么邏輯也沒有,我們還是不得不在a.cpp中寫上構(gòu)造函數(shù)和析構(gòu)函數(shù)的實現(xiàn)。有了=default關(guān)鍵字,我們就可以在a.h中直接寫成:

1.6.4=delete語法

既然有強制讓編譯器生成構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、operator=的語法,那么也應該有禁止編譯器生成這些函數(shù)的語法,沒錯,就是=delete。

在C++98/03規(guī)范中,如果我們想讓一個類不能被拷貝(即不能調(diào)用其拷貝構(gòu)造函數(shù)),則可以將其拷貝構(gòu)造函數(shù)和operator=函數(shù)定義成private的:

通過以上代碼利用a1構(gòu)造a2時,編譯器會提示錯誤:

我們利用這種方式間接實現(xiàn)了一個類不能被拷貝的功能,這也是繼承自boost::noncopyable 的類不能被拷貝的實現(xiàn)原理。現(xiàn)在有了=delete 語法,我們直接使用該語法禁止編譯器生成這兩個函數(shù)即可:

一般在一些工具類中,我們不需要用到構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、operator=這4個函數(shù),為了防止編譯器自己生成,同時為了減小生成的可執(zhí)行文件的體積,建議使用=delete語法禁止編譯器為這4個函數(shù)生成默認的實現(xiàn)代碼,例如:

主站蜘蛛池模板: 汪清县| 普兰县| 淅川县| 阜城县| 五寨县| 盐城市| 修文县| 新沂市| 渝中区| 维西| 内乡县| 米易县| 禹州市| 措美县| 高陵县| 西城区| 二手房| 阿拉善右旗| 白玉县| 元谋县| 佛学| 象山县| 万州区| 汕尾市| 诸暨市| 临安市| 休宁县| 磐安县| 高州市| 海阳市| 全南县| 崇义县| 赣州市| 自治县| 盐城市| 九寨沟县| 谷城县| 景泰县| 沈丘县| 特克斯县| 广东省|