為了能夠編寫適當的catch子句,了解乙個函式是否丟擲異常或會丟擲哪些異常對函式的使用者來說是很有幫助的。
而我們可以通過異常說明進行對乙個函式的異常進行說明,如果函式丟擲異常,被丟擲的異常將是包含在該說明中的一種或是從列出的異常中派生的型別。
異常說明有如下的幾種形式:
1. 指定異常
t funnname( parameterlist )throw( t1, t2,····,tn);
其中t是型別,parameterlist是引數列表, 而型別t1, t2,····,tn是函式會丟擲的異常。
2. 不丟擲異常
t funnname( parameterlist )throw( );
丟擲異常型別列表為空,表示的是該函式不丟擲任何型別異常。
3. 丟擲任意型別的異常
t funnname( parameterlist );
這表示該函式可以丟擲任意型別的異常。
下面通過一段簡單的**來說明異常說明的特別之處
#include class demo
;using namespace std;
double divd(int a, int b) throw(int) //異常說明,表示函式divd會丟擲型別為int的異常
int main()
catch(demo) //捕獲異常型別demo
catch(int) //捕獲異常型別int
{cout<<"zero"<
奇怪了,在 divd 函式的宣告中,只說明了丟擲型別為 int 的異常,為什麼其函式內丟擲的異常型別卻為demo呢?
我們可以暫時理解為:在某函式的異常說明中的列出的型別與該函式內丟擲的異常型別不完全匹配時, 但在異常處理**中的catch有對其型別的捕獲, 所以程式執行正常。
好,下面我們根據異常說明進行一些修改
double divd(int a, int b) throw( ) //將throw(int) 改為 throw( )
修改之後,編譯執行,看到的輸出結果還是:divided by zero
根據上面對異常說明的三種形式介紹,我們知道在函式宣告後面新增 throw()的意思是說明了此函式不會丟擲任何的異常。那為什麼這裡丟擲了而且又**獲呢?
其實,在編譯的時候,編譯器不能也不會試圖驗證異常說明。因不能在編譯時檢查異常說明,異常說明的應用通常是有限的!
修改後的 divd 函式內繼續編寫有丟擲異常的**, 編譯後再次執行程式,其輸出結果也表示異常機制執行正常。
其原因就如上述所說的理解那樣:編譯器不會對異常說明進行檢測,異常說明更多的是寫給函式的使用者看。
而在一開始函式異常說明的型別與實際丟擲的異常型別不匹配的情況中,同樣由於 「編譯器不會對異常說明進行檢測」 的原因,所以編譯通過,異常機制執行正常。
總結:異常說明還是有用的!但更多是寫給函式使用者看的。讓函式使用者清楚知道丟擲的異常型別,從而更好和正確地在運用此函式時,編寫對其的異常檢測。
由於初學者在學語法的時候,更多的只是看書,不進行實踐驗證。就算實踐驗證了,也可能只是照書上**敲,看看執行結果是否一樣。這裡給出乙個建議:初學者在學習語法的時候,應該多上機實踐驗證書上語法的準確性,就算執行結果與書上一致,也應該多動腦筋,對其進行變形或改動。這樣往往能學到的東西和印象都會更深的!
C 異常之異常說明
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!為了能夠編寫適當的catch子句,了解乙個函式是否丟擲異常或會丟擲哪些異常對函式的使用者來說是很有幫助的。而我們可以通過異常說明進行對乙個函式的異常進行說明,如果函式丟擲異常,被丟擲的異常將是包含在該說明中的一種或是從列出的異常中派生的型別。異常說...
C 異常之異常說明
為了能夠編寫適當的catch子句,了解乙個函式是否丟擲異常或會丟擲哪些異常對函式的使用者來說是很有幫助的。而我們可以通過異常說明進行對乙個函式的異常進行說明,如果函式丟擲異常,被丟擲的異常將是包含在該說明中的一種或是從列出的異常中派生的型別。異常說明有如下的幾種形式 1.指定異常 t funnnam...
C 函式異常說明
為了能夠編寫適當的catch子句,了解乙個函式是否丟擲異常或會丟擲哪些異常對函式的使用者來說是很有幫助的。而我們可以通過異常說明進行對乙個函式的異常進行說明,如果函式丟擲異常,被丟擲的異常將是包含在該說明中的一種或是從列出的異常中派生的型別。異常說明有如下的幾種形式 1.指定異常 t funnnam...