一、簡介
在C++語言中,異常處理包括:throw表達式
,try語句塊
,一套異常類
。其中,異常類用於在throw表達式和相關的catch子句之間傳遞異常的具體信息。exception頭文件定義了最普通的異常類exception,它只報告異常的發生,不提供任何額外信息。以下是定義在stdexcept頭文件中的常用的異常類:
異常類 | 解釋 |
---|---|
exception | 最常見的問題 |
runtime_error | 只有在運行時才能檢測出的問題 |
range_error | 運行時錯誤:生成的結果超出了有意義的值域范圍 |
overflow_error | 運行時錯誤:計算上溢 |
underflow_error | 運行時錯誤:計算下溢 |
logic_error | 程序邏輯錯誤 |
domain_error | 邏輯錯誤:參數對應的結果值不存在 |
invalid_argument | 邏輯錯誤:參數無效 |
length_error | 邏輯錯誤:試圖創建一個超過該類型最大長度的對象 |
out_of_range | 邏輯錯誤:使用一個超出有效范圍的值 |
異常類只定義了一個名為what的成員函數,該函數沒有任何參數,返回值是一個指向C風格字符串的const char*。
二、基本用法
直接貼代碼,簡單測試一下:
#include <stdexcept>
#include <iostream>
using namespace std;
void test() {
throw runtime_error("just for test!");
}
int main() {
try {
test();
} catch(runtime_error err) {
cout << err.what() << endl;
}
return 0;
}
/*
* 執行的結果不出意料,便是:just for test!
* 可以有多個catch語句塊
* 找到了匹配的runtime_error便執行相應的catch語句塊代碼
*/
注意:當執行一個throw時,跟在throw后面的語句將不再被執行。且只有在catch語句塊中可以使用
throw;
這樣的語句,表示當前的catch語句不足與完整地處理好這個異常,於是決定由更上一層的函數接着處理。
三、noexcept
概括來說,這個關鍵字有兩種用法:作為函數限定符,作為一個一元運算符返回一個bool類型的右值常量表達式。
第一個用法中,noexcept放在函數的后面,一般而言,對於成員函數來說,放在const后面,而放在final、override或虛函數的=0之前。其表示該函數不會拋出異常,但如下情況也可以順利編譯:
void f() noexcept {
throw exception();
}
需要注意的是,函數指針及該函數指向的函數必須具有一致性的異常說明,如下:
void (*pf1)(int) noexcept;
void f() noexcept {}
void t() {}
pf1 = f; //正確,因為f能保證不拋出異常
pfi = t; //錯誤,因為t不能保證
第二個用法中,可以如下使用:
noexcept(f()) //若f保證不拋出異常,則返回true
//一個常用用法,等價於void t() {}
void t() noexcept(false) {}
//以下保證f和g的異常類型一致
void f() noexcept(noexcept(g()));
四、定義自己的異常類
假設你想設計一個異常類,名為test_error,其的效果和runtime_error一樣,可以用如下代碼:
class test_error : public runtime_error {
public:
explicit test_error(const string &s):
runtime_error(s) {}
};