日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【C++基础】C++11的noexcept声明符 与 异常传播

發布時間:2023/12/1 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C++基础】C++11的noexcept声明符 与 异常传播 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • C++ noexcept:
    • 1、用途
    • 2、用法
      • 1、noexcept聲明符的用法:
      • 2、noexcept運算符的用法
  • 異常傳播
    • 1、異常傳播的定義
    • 2、異常傳播中的規則
    • 3、異常傳播的代價

C++ noexcept:

1、用途

C++11使用noexcept指明函數是否拋出異常:

若函數不拋異常,則可做編譯優化
即便函數拋異常,也不再說明所拋異常類型(簡化)

注意,C++03將throw(ExceptionType)放到函數后面,說明函數會拋出什么類型的異常,也被稱為“異常規約”
java用 throws關鍵字做同樣的事情

2、用法

1、noexcept聲明符的用法:

void foo() noexcept {} //函數不拋異常void foo() noexcept(true) {} // noexcept(true)等價于noexceptvoid foo() {} // 可能會拋出異常void foo() noexcept(false) {} // noexcept(false)等價于什么也不寫,可能會拋出異常

需要注意的地方:
1、noexcept不能用于區分重載函數。

2、如果我們聲明函數時說了它不拋異常,但是又在noexcept函數中拋出異常,這就等于調用std::terminate(),終結程序的運行。

void f() { /* 潛在拋出異常 */ } void g() noexcept {f(); // 合法,即 使 f 拋出 throw 42; // 合法,等效于調用 std::terminate }


編譯時會報警告:

主函數調用foo(),運行時程序會終止:

2、noexcept運算符的用法

bool noexcept( expression )

noexcept 運算符進行編譯時檢查,若表達式聲明為不拋出任何異常則返回 true。
noexcept (may_throw())返回false,表明可能會拋異常。
noexcept (no_throw())返回true,表明不拋異常。

void may_throw(); void no_throw() noexcept; int main() {std::cout << std::boolalpha<< "Is may_throw() noexcept? "<< noexcept (may_throw()) << '\n'<< "Is no_throw() noexcept? "<< noexcept (no_throw()) << '\n'; }

異常傳播

1、異常傳播的定義

嵌套的函數調用,每個函數中都有 try-catch 塊,內層函數拋出異常,這時候會出現異常傳播

如圖,func3中出現了異常,如果沒有被func2中的catch捕獲到的話,異常會隨著函數的返回,交給函數的上一級(func1)處理,如果func1也處理不了,則交給main函數處理,如果main函數處理不了,程序會崩潰。
需要注意的地方:

  • try塊中拋出異常的語句后面的語句
  • catch的異常類型與所需匹配的異常實例的類型
  • 2、異常傳播中的規則

    try-catch的執行規則

  • try塊中的異常:拋異常的語句后的塊代碼都被跳過,并開始找exception handler的代碼(即找catch代碼)
  • 找exception handler的流程:沿函數調用的鏈反向尋找(1) 按catch塊的順序對比,找到則執行catch塊代碼(2) 找不到,退出當前函數,將異常傳給調用當前函數的函數
  • 仍然以上圖調用鏈為例:

    Quiz: function3拋出

  • Exception3,執行哪些statement?
    執行Process ex3 -> statement6-> statement3-> statement4-> statement1-> statement2;
  • Exception2,執行哪些statement?
    執行Process ex2 ->statement4-> statement1-> statement2;
  • Exception1,執行哪些statement?
    執行Process ex1 -> statement2;
  • Exception0,執行哪些statement?
    返回到主函數,程序崩潰
  • 3、異常傳播的代價

    C++引入的異常處理會為程序帶來額外開銷和代價。

    (1)項目中使用異常,需要考慮與未使用異常的第三方和舊項目代碼的整合問題,避免出現一異常安全問題;
    (2)異常使用不當,容易造成內存泄漏和程序崩潰,比如函數內拋出異常需要注意棧展開導致的內存泄露,析構函數拋出異常將程序置于不確定狀態等;
    (3)異常的跳轉會徹底擾亂程序的執行流程并難以判斷,給代碼調試和維護增加難度;
    (4)為保證寫出異常安全的代碼,往往需要借用C++其它特性,如智能指針,這又進一步加劇了代碼可讀性的惡化與程序的時空開銷,包括編譯時間的延長,運行效率的較低以及代碼尺寸的增大。

    總結

    以上是生活随笔為你收集整理的【C++基础】C++11的noexcept声明符 与 异常传播的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。