C++ Primer 5th笔记(chap 18 大型程序工具)noexcept
1. 通過提供 noexcept 說明 ( noexcept specification ) 指定某個函數不會拋出異常。 其形式是關鍵字 noexcept 緊跟在函數的參數列表后面
{// 緊跟在函數的參數列表后面// 該說明應該在函數的尾置返回類型之前// 在成員函數中,noexcept說明符應該出現在const以及引用限定之后// 而在final,override,或者虛函數的=0之前。void recoup(int) noexcept;//不會拋出異常void alloc(int);//可能會拋出異常//noexcept要么出現在該函數的所有聲明和定義語句中//要么一次也不出現。//我們也可以在函數指針的聲明和定義中指定noexcept//在typedef或類型別名中不能出現noexcept }對于一個函數來說, noexcept 說明要么出現在該函數的所有聲明語句和定義語句中, 要么一次也不出現。
-
該說明應該在函數的尾置返回類型之前。
-
也可以在函數指針的聲明和定義中指定 noexcept。
-
在 typedef 或類型別名中則不能出現 noexcept。
-
在成員函數中, noexcept 說明符需要跟在 const 及引用限定符之后, 而在 final、 override 或虛函數的=0 之前
1.1 違反異常說明
編譯器并不會在編譯時檢查noexcept說明。如果在一個函數中說明了noexcept的同時又含有throw語句,或者調用可能拋出異常的其他函數,編譯器將會順序編譯通過,并不會因為這種違反異常說明滾的情況而報錯。(又可能會有編譯器會提出警告)
// 盡管該函教明顯違反了異常說明, 但它仍然可以順利編譯通過 void f ( ) noexcept //承諾不會拋出異常 {throw exception ( ); / / 違反了異常說明 }因此可能會出現一個函數既聲明了不會拋出異常,而又拋出了異常。此時,一旦拋出異常,程序就會調用terminate以確保遵守不在運行時拋出異常的承諾。上述過程對是否執行棧展開沒有約定。
因此noexcept用在兩種情況。
- 我們確認函數不會拋出異常
- 我們根本不會處理該異常
1.2 異常說明的實參
noexcept 說明符接受一個可選的實參, 該實參必須能轉換為 bool 類型: 如果實參是 true, 則函數不會拋出異常; 如果實參是 false, 則函數可能拋出異常:
void recoup (int) noexcept (true); / / recoup 不會拋出異常 void alloc (int ) noexcept ( false);/ / alloc 可能拋出異常1.3 noexcept 運算符 (noexcept operator)
noexcept 運算符是一個一元運算符, 它的返回值是一個 bool 類型的右值常量表達式,用于表示給定的表達式是否會拋出異常
和sizeof一樣,noexcept也不會對該表達式求值。
1.4 異常說明與指針、 虛函數和拷貝控制
1.4.1 指針
函數指針及該指針所指的函數必須具有一致的異常說明。
- 如果我們為某個指針做了不拋出異常的聲明, 則該指針將只能指向不拋出異常的函數。
- 如果我們顯式或隱式地說明了指針可能拋出異常, 則該指針可以指向任何函數, 即使是承諾了不拋出
異常的函數也可以
1.4.2 虛函數
如果一個虛函數承諾了它不會拋出異常,則它后續的派生類的虛函數也必須做出同樣的承諾。
如果基類的虛函數允許拋出異常時,我們可以設置派生類對應的函數不能拋出異常,當然也可以是允許拋出異常
1.4.3 拷貝控制成員
- 當編譯器合成拷貝控制成員時,同時也生成一個異常說明符。
- 如果對所有成員和基類的所有操作都承諾了不會拋出異常,則合成的成員是noexcept的。
- 如果合成成員調用的任意一個函數可能會拋出異常,則合成的成員是noexcept(false)的。
-我們定義了一個析構函數,但是沒有為它提供異常說明,編譯器將會合成一個,合成的異常說明符將與假設編譯器為類合成的析構函數時所得的異常說明一致。
總結
以上是生活随笔為你收集整理的C++ Primer 5th笔记(chap 18 大型程序工具)noexcept的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++ Primer 5th笔记(cha
- 下一篇: C++ Primer 5th笔记(cha