C++解析-外傳篇(2):函式的異常規格說明
阿新 • • 發佈:2018-12-11
0.目錄
1.異常規格說明
2.unexpected() 函式
3.小結
1.異常規格說明
問題:
如何判斷一個函式是否會丟擲異常,以及丟擲哪些異常?
- C++提供語法用於宣告函式所丟擲的異常
- 異常宣告作為函式宣告的修飾符,寫在引數列表後面
異常規格說明的意義:
- 提示函式呼叫者必須做好異常處理的準備
- 提示函式的維護者不要丟擲其它異常
- 異常規格說明是函式介面的一部分
問題:
如果丟擲的異常不在宣告列表中,會發生什麼?
下面的程式碼的輸出什麼?
示例——異常規格之外的異常:
#include <iostream> using namespace std; void func() throw(int) { cout << "func()"; cout << endl; throw 'c'; } int main() { try { func(); } catch(int) { cout << "catch(int)"; cout << endl; } catch(char) { cout << "catch(char)"; cout << endl; } return 0; }
執行結果為:
[[email protected] Desktop]# g++ test.cpp
[[email protected] Desktop]# ./a.out
func()
terminate called after throwing an instance of 'char'
Aborted (core dumped)
(不同編譯器執行結果不一樣。)
2.unexpected() 函式
- 函式丟擲的異常不在規格說明中,全域性 unexpected() 被呼叫
- 預設的 unexpected() 函式會呼叫全域性的 terminate() 函式
- 可以自定義
- 注意:不是所有的C++編譯器都支援這個標準行為
unexpected() 函式的替換:
- 自定義一個無返回值無引數的函式
- 能夠再次丟擲異常
- 當異常符合觸發函式的異常規格說明時,恢復程式執行
- 否則,呼叫全域性 terminate() 函式結束程式
- 能夠再次丟擲異常
- 呼叫 set_unexpected () 設定自定義的異常函式
- 引數型別為
void (*) ()
- 返回值為預設的 unexpected() 函式入口地址
- 引數型別為
示例1——自定義 unexpected() 函式:
#include <iostream>
#include <cstdlib>
#include <exception>
using namespace std;
void my_unexpected()
{
cout << "void my_unexpected()" << endl;
exit(1);
}
void func() throw(int)
{
cout << "func()";
cout << endl;
throw 'c';
}
int main()
{
set_unexpected(my_unexpected);
try
{
func();
}
catch(int)
{
cout << "catch(int)";
cout << endl;
}
catch(char)
{
cout << "catch(char)";
cout << endl;
}
return 0;
}
執行結果為:
[[email protected] Desktop]# g++ test.cpp
[[email protected] Desktop]# ./a.out
func()
void my_unexpected()
將exit();
改為throw 1;
後的執行結果:
示例2——自定義 unexpected() 函式:
void my_unexpected()
{
cout << "void my_unexpected()" << endl;
// exit(1);
throw 1;
}
執行結果為:
[[email protected] Desktop]# g++ test.cpp
[[email protected] Desktop]# ./a.out
func()
void my_unexpected()
catch(int)
(程式恢復執行了。)
(unexpected() 函式是正確處理異常的最後機會,如果沒有抓住這次機會,全域性的 terminate() 函式就會被呼叫,當前程式就只能以異常結束告終。)
3.小結
- C++中的函式可以宣告異常規格說明
- 異常規格說明可以看作介面的一部分
- 函式丟擲的異常不在規格說明中,unexpected() 被呼叫
- unexpected() 中能夠再次丟擲異常
- 異常能夠匹配,恢復程式的執行
- 否則,呼叫 terminate() 結束程式