【C++ 筆記】例外處理(Exception Handling) - part 28
【C++ 筆記】例外處理(Exception Handling) - part 28
很感謝你點進來這篇文章。
你好,我並不是什麼 C++、程式語言的專家,所以本文若有些錯誤麻煩請各位鞭大力一點,我極需各位的指正及指導!!本系列文章的性質主要以詼諧的口吻,一派輕鬆的態度自學程式語言,如果你喜歡,麻煩留言說聲文章讚讚吧!
例外是什麼?
例外(exception)又稱為異常,是指程式在執行過程當中發生的例外情況或錯誤事件。如將兩數相除的過程中,有一個數除於 0,這會是一個例外,因為可能會導致未定義的錯誤。
而處理例外的過程就稱為例外處理,對 XD。
基本例外處理
try-catch
語法:
1 | try { |
當 try 區塊發生例外的時候,於 try 的區塊會停止,catch 就會去捕捉這個例外,然後在 catch 區塊裡面做一些處理。
ExceptionType e:看 catch 要捕捉什麼,如 int e 就是捕捉 int 型態的例外。
throw 拋出例外
用 throw 關鍵字拋出例外,catch 會偵測這個例外是什麼東西,如果符合的話就會去處理,如:
1 | try { |
範例:
1 |
|
Output:
1 | Caught an integer exception with value : 10 |
標準例外
標準例外是 C++ STL 裡面定義的一組例外類別,大多被定義在 <stdexcept> 或 <typeinfo>(如 bad_cast) 中。
主要分成兩大類:
- 邏輯錯誤(logic_error)
- 執行期錯誤(runtime_error)
以下是標準錯誤的層次結構圖:

Image Source:GeeksForGeeks
以下是為以上層次結構圖製作的表格:
| 例外類型 | 說明 |
|---|---|
std::logic_error | 邏輯錯誤。表示程式中存在不合理的邏輯問題,通常是可預先檢查出的錯誤。 |
std::invalid_argument | 無效的參數。通常因傳遞了錯誤或非法的參數值而引發。屬於 logic_error 的子類。 |
std::domain_error | 數學定義域錯誤。當參數不在函數允許的數學定義域內時拋出,例如平方根的負數輸入。屬於 logic_error 的子類。 |
std::length_error | 長度錯誤。當容器長度超過其最大容量限制時拋出。屬於 logic_error 的子類。 |
std::out_of_range | 超出範圍。當使用無效索引存取容器元素時拋出。屬於 logic_error 的子類。 |
std::runtime_error | 執行期間錯誤。表示在執行階段發生非預期狀況,無法在編譯期間預測。 |
std::range_error | 範圍錯誤。當數值運算結果超出有效範圍但仍合法(如浮點精度損失)時拋出。屬於 runtime_error 的子類。 |
std::overflow_error | 溢位錯誤。當數值計算超過資料型態的上限時拋出。屬於 runtime_error 的子類。 |
std::underflow_error | 下溢錯誤。當浮點數計算結果太接近零而無法正確表示時拋出。屬於 runtime_error 的子類。 |
std::bad_alloc | 記憶體配置失敗。當 new 無法配置足夠記憶體時拋出。屬於 std::exception 的子類。 |
std::bad_function_call | 錯誤的函數呼叫。當呼叫尚未設定目標的 std::function 物件時拋出。 |
std::bad_cast | 錯誤的型態轉換。當使用 dynamic_cast 進行不合法的轉型時拋出。 |
在以上每個標準例外中,都有一個 what() 方法提供這些標準例外的相關資訊。
以下是個範例:
1 |
|
Output:
1 | 計算 -5 的平方根... |
catch 多個例外
不只是 catch 一個例外而已,也可以多個例外:
1 | try { |
以下是個範例:
1 |
|
catch 所有例外
就是 catch(...) 即可捕捉所有的例外,延續上個範例,增加這個上去:
1 |
|
當輸入 a = 9999, b = 任意數時,就會輸出「捕捉到未知的例外」。
catch by reference
這個方法只需要傳遞對拋出例外的參考,不需要建立他的 copy,能減少這部分的效能開銷。除了這之外,主要拿來捕捉多型的例外。
1 |
|
Output:
1 | 捕捉到例外: 發生錯誤:無效的操作 |
例外規格(Exception Specification)
noexceptornoexcept(true):如其名,告訴函數保證不會引發例外。noexcept(false):表示可能會拋出例外。若未使用任何的例外規格,這會是預設的,也就是說可加可不加,加了會提升可讀性。
1 | void func1(int a) noexcept { |
總結
什麼是例外(Exception)?
- 例外是指程式執行過程中發生的異常狀況或錯誤事件,如除數為 0。
- 例外處理是指對這些異常狀況進行捕捉與處理的機制,避免程式異常終止。
基本例外處理語法
- 使用
try區塊包著可能拋出例外的程式碼。 - 使用
catch區塊捕捉並處理特定類型的例外。
語法:
1 | try { |
throw 關鍵字用於拋出例外:
1 | throw val; |
標準例外類別
定義於 <stdexcept> or <typeinfo>。
分為兩大類:
- 邏輯錯誤(logic_error):程式邏輯錯誤,可預先檢查。
- 執行期錯誤(runtime_error):執行時非預期錯誤。
標準例外表:
| 例外類型 | 說明 |
|---|---|
std::logic_error | 邏輯錯誤。表示程式中存在不合理的邏輯問題,通常是可預先檢查出的錯誤。 |
std::invalid_argument | 無效的參數。通常因傳遞了錯誤或非法的參數值而引發。屬於 logic_error 的子類。 |
std::domain_error | 數學定義域錯誤。當參數不在函數允許的數學定義域內時拋出,例如平方根的負數輸入。屬於 logic_error 的子類。 |
std::length_error | 長度錯誤。當容器長度超過其最大容量限制時拋出。屬於 logic_error 的子類。 |
std::out_of_range | 超出範圍。當使用無效索引存取容器元素時拋出。屬於 logic_error 的子類。 |
std::runtime_error | 執行期間錯誤。表示在執行階段發生非預期狀況,無法在編譯期間預測。 |
std::range_error | 範圍錯誤。當數值運算結果超出有效範圍但仍合法(如浮點精度損失)時拋出。屬於 runtime_error 的子類。 |
std::overflow_error | 溢位錯誤。當數值計算超過資料型態的上限時拋出。屬於 runtime_error 的子類。 |
std::underflow_error | 下溢錯誤。當浮點數計算結果太接近零而無法正確表示時拋出。屬於 runtime_error 的子類。 |
std::bad_alloc | 記憶體配置失敗。當 new 無法配置足夠記憶體時拋出。屬於 std::exception 的子類。 |
std::bad_function_call | 錯誤的函數呼叫。當呼叫尚未設定目標的 std::function 物件時拋出。 |
std::bad_cast | 錯誤的型態轉換。當使用 dynamic_cast 進行不合法的轉型時拋出。 |
註:每個標準例外都有 what() public 方法可取得錯誤訊息。
多重 catch 與 catch 所有例外
可以有多個 catch:
1 | try { |
catch(...)用來捕捉所有未知例外。
以參考捕捉例外(catch by reference)
使用 catch (ExceptionType& e) 避免 copy,提高效率,也能捕捉多型例外。
例外規格(Exception Specification)
- noexcept:保證函數不會拋出例外。
- noexcept(false):函數可能會拋出例外,為預設行為。
參考資料
例外規格(Exception Specifications)
How to Catch All Exceptions in C++? - GeeksforGeeks


