爲了能夠編寫適當的catch子句,瞭解一個函數是否拋出異常或會拋出哪些異常對函數的用戶來說是很有幫助的。
而我們可以通過 異常說明 進行對一個函數的異常進行說明, 如果函數拋出異常,被拋出的異常將是包含在該說明中的一種或是從列出的異常中派生的類型。
異常說明有如下的幾種形式:
1. 指定異常
T funNname( parameterlist ) throw( T1, T2,····,Tn);
其中 T 是類型, parameterlist 是參數列表, 而類型 T1, T2,····,Tn 是函數會拋出的異常。
2. 不拋出異常
T funNname( parameterlist ) throw( );
拋出異常類型列表爲空,表示的是該函數不拋出任何類型異常。
3. 拋出任意類型的異常
T funNname( parameterlist );
這表示該函數可以拋出任意類型的異常。
下面通過一段簡單的代碼來說明異常說明的特別之處
- #include <iostream>
- class demo
- {
- };
- using namespace std;
- double divd(int a, int b) throw(int) //異常說明,表示函數divd會拋出類型爲int的異常
- {
- if(b == 0) throw demo(); //拋出類型爲demo的異常
- return a/b;
- }
- int main()
- {
- try
- {
- divd(1,0);
- }
- catch(demo) //捕獲異常類型demo
- {
- cout << " divided by zero " << endl;
- }
- catch(int) //捕獲異常類型int
- {
- cout<<"zero"<<endl;
- }
- return 0;
- }
奇怪了,在 divd 函數的聲明中,只說明瞭拋出類型爲 int 的異常,爲什麼其函數內拋出的異常類型卻爲demo呢?
我們可以暫時理解爲:在某函數的異常說明中的列出的類型與該函數內拋出的異常類型不完全匹配時, 但在異常處理代碼中的catch有對其類型的捕獲, 所以程序運行正常。
好,下面我們根據異常說明進行一些修改
- double divd(int a, int b) throw( ) //將throw(int) 改爲 throw( )
根據上面對異常說明的三種形式介紹,我們知道在函數聲明後面添加 throw()的意思是說明了此函數不會拋出任何的異常。那爲什麼這裏拋出了而且又被捕獲呢?
其實,在編譯的時候,編譯器不能也不會試圖驗證異常說明。因不能在編譯時檢查異常說明,異常說明的應用通常是有限的!
總結:異常說明還是有用的!但更多是寫給函數用戶看的。讓函數用戶清楚知道拋出的異常類型,從而更好和正確地在運用此函數時,編寫對其的異常檢測。