在C++的發展過程中,爲了實際的需要,引入了異常處理機制。程序中常見的錯誤:語法錯誤和運行錯誤,語法錯誤一般都是在編譯時候發現的,編譯器基本上都會報出錯誤的具體位置,因此這類錯誤一般都是比較好修改,運行錯誤一般不容易進行調試,比如說,程序崩潰(一般是由於棧溢出),運行結果錯誤(一般是算法的邏輯結構有問題)、程序非正常終止等現象。C++中引入異常處理(對運行時出現的差錯進行處理),能夠極大地提高程序的容錯能力。
C++處理異常是利用try(檢查)、throw(拋出)、catch(捕捉)三部分來進行處理的,把有可能出現異常的代碼放到try塊中,throw用來拋出一個異常信息,catch的參數一般爲拋出的信息類型,如果拋出的類型和catch捕捉的類型相同時候,則就進行對應的異常處理。
下面是一個異常處理的例子:
#include <iostream>
using namespace std;
#include <math.h>
/*定義計算三角形面積的函數(利用海倫公式S = sqrt(q*(q - a)*(q - b)*(q - c)),其中q = (a+b+c)/2)滿足三角形的條件:a+b>c a+c>b b+c>a(a,b,c都大於0)
*/
double triangle(double a, double b, double c)
{
double q = (a + b + c) / 2;
if (a + b <= c || a + c <= b || b + c <= a) //a,b,c這三個長度不能構成三角形
{
throw a; //拋出異常
}
return sqrt(q * (q - a) * (q - b) * (q - c)); //求三角形面積
}
int main()
{
double a, b, c;
cin >> a >> b >> c;
try //檢查是否出現異常,異常出現在兩個方面,一是a,b,c中有可能爲負數,或者兩邊之和不大於第三邊
{
while (a > 0 && b > 0 && c > 0)
{
cout << triangle(a, b, c) << endl;
cin >> a >> b >> c;
}
}
catch (double) //捕捉異常並處理
{
cout << a << " " << b << " " << c << "this is not triangle!" << endl;
}
system("pause");
return 0;
}
在上面的例子中,三角形的三邊長度有可能不滿足構成三角形的條件,會發生異常,try塊中爲可能發生異常的代碼,在triangle函數中,對三邊的長度進行條件的判斷,如果不滿足,則將異常進行拋出,這時程序會返回主調函數中尋找對應的catch塊,上面的throw a;a的數據類型爲double類型,main函數中catch進行捕捉的類型也爲double類型,兩者相匹配,就執行catch塊中的處理代碼,然後程序不會返回被調用函數拋出的位置,而是直接執行catch後面的代碼。
注意:
(1)try塊中的代碼不會影響原來執行的順序,如果try中沒有發生異常就會不執行catch塊中的代碼,而直接執行catch之後的代碼。若出現異常,對異常進行拋出,流程會立即離開本函數,返回上一級的函數,則不會執行本函數throw後面的代碼。
(2)流程返回到上一級函數時,系統會尋找與之匹配的catch塊,進而執行。執行完catch塊中的代碼,緊接着執行catch塊後面的代碼,直到程序結束。
(3)被檢測的部分必須放在try塊中,否則會不起作用。catch塊不能夠單獨使用,但是try塊可以單獨使用,但是隻進行檢查,而不進行錯誤處理。try和catch塊中必須使用花括號括起來,哪怕塊中只有一個語句。一個程序中只能有一個try塊,但可以有多個catch塊,可以進行多個問題的處理。catch只會檢查參數的類型,不檢查參數的值。
(4)若catch(doube b){}; 則是將參數的double類型和throw a;的類型進行比較,然後將a的值賦值給b,即就是b=a;
若catch(...){}; 則是不論什麼類型,都會執行catch塊中的代碼。一般這樣的catch會放在程序的最後,對於一些意想不到的異常進行處理,如果放在最開始則後面的catch就不會被執行。
(5)try-catch可以和throw在同一個函數中,也可以不在同一個函數中,若不在一個函數中,它們的catch執行滿足下圖的關係:
(6)如果throw的異常信息沒有找到與之相匹配的catch,系統會自動調用一個系統函數terminate函數,使得程序停止運行。
本文出自 “無心的執着” 博客,轉載請與作者聯繫!