国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++中的異常處理

2019-11-06 08:54:35
字體:
來源:轉載
供稿:網友

異常處理概念

所有的代碼都有可能不按照預定義的方式運行,成為程序異常。

C++中提供了trycatch語句塊對可能產生異常的代碼進行分開處理:

try語句塊處理正常邏輯catch語句塊處理異常

C++語言中通過throw語句引發一個異常。

應用舉例: 這里寫圖片描述

在上面的例子中,throw扔出的異常值被catch抓到,catch的參數error就是throw扔出的異常值。

throw語句

throw語句用于將異常“對象”拋出。 而且throw拋出的異常必須有catch來進行處理。

throw語句將異常拋出,如果在當前函數中沒有try…catch語句能夠處理該異常,則當前函數將立即返回。

異常被傳遞到上層調用函數,仍然需要try…catch語句 進行處理,如果上層函數也沒有能力處理該異常,則異 常繼續向更上層函數的函數傳遞。

如果在函數調用棧中的所有函數都無法處理拋出的異常,則程序異常中止

try…catch… 語句

同一個try語句塊可以跟上多個catch語句塊。 同一個try語句塊可以拋出多種不同類型的異常。 不同類型的異常由不同的catch語句塊負責處理。 異常被拋出后會自上而下逐一匹配catch語句塊。

異常匹配時,不會進行默認類型轉換。程序會嚴格匹配每個類型,不會類型轉換。

這些異常是通過異常的數據類型進行區分的。

程序代碼舉例:

#include <cstdlib>#include <iostream>using namespace std;int test(int i){ if( i == 1 ) { throw -1;//拋出 int 型異常 } if( i == 2 ) { throw "ERROR";//拋出 字符串 型異常 } if( i == 3 ) { throw 0.5;//拋出 double 型異常 }// if( i == 4 )// {// throw 'd';//拋出 字符char 型異常,但是沒有相應catch,程序退出 // } return i;}int main(int argc, char *argv[]){ for(int i=0; i<5; i++) { try { cout<<test(i)<<endl; } catch(int e) //處理int型異常 { cout<<"Int: "<<e<<endl; } catch(const char* e)//處理字符串型異常 { cout<<"const char*: "<<e<<endl; } catch(double e)//處理double型異常 { cout<<"double: "<<e<<endl; } //沒有處理字符類型的catch,因此不能拋出字符類型的異常 } cout << "PRess the enter key to continue ..."; cin.get(); return EXIT_SUCCESS;}

異常處理深入

有時在工程中只關心是否產生了異常,而不關心具體的異常類型。

C++中的catch語句可以使用 捕獲所有的異常。

如下圖所示: 這里寫圖片描述

catch(…)可以捕獲所有異常但卻無法得到異常信息。 catch(…)一般作為最后一個異常處理塊出現。在一些現代的編譯器中,如果catch(…)不是最后一個異常處理,程序會報錯。

看見代碼中的catch就要意識到這里在處理異常情況,而且異常是在對應的try中產生的。

在catch語句塊中仍然可以拋出異常,并且需要到外層 程序的catch中進行處理。

在catch(…)語句塊中,可以通過不帶參數的throw語 句拋出已經捕獲到的捕獲的異常。 如下圖所示: 這里寫圖片描述

異常與對象

不要在構造函數中拋出異常。 在構造函數可能申請系統資源,而在構造函數中拋出異常會導致對象構造不完全。 不完全對象的析構函數是不會被調用的,因此可能造成資源泄漏。

如下圖所示: 這里寫圖片描述 在上面的例子中,在為p分配了20字節的空間之后,拋出異常,無法析構,浪費了20字節的空間。

工程中對異常的應用

在工程中會定義一系列的異常類。 通過繼承,可以得到一個異常類族。 每個類代表工程中可能出現的一種異常類型。 為了避免對象構造與拷貝的開銷,在定義catch語句塊時使用引用作為參數。

在工程中可以使用標準庫中的異常類。 可將標準庫中的異常類作為基類派生新的異常類。 標準庫中的異常都是從exception類派生的。

exception類有兩個主要的分支: logic_error用于描述程序中出現的邏輯錯誤。 如:傳遞無效參數、除數為0 runtime_error用于描述無法預料的事件所造成的錯誤。 如:內存耗盡,硬件錯誤

以上兩個分支都是exception類派生的兩個類。 標準庫中的異常類: 這里寫圖片描述 logic_ error和runtime_ error都提供了一個參數為字符串的構造函數,這樣就可以保持錯誤信息。 通過 what() 成員函數就可以得到錯誤的信息。

工程應用舉例:

#include <cstdlib>#include <iostream>#include <stdexcept>//異常類 頭文件 using namespace std;//自定義 divide_by_zero(除數為0)異常類//繼承自 logic_error 異常類, 邏輯錯誤 class divide_by_zero : public logic_error{public: divide_by_zero(const char* s) : logic_error(s) { }//自定義構造函數,參數列表為父類構造函數 };double Div(double a, double b){ if( (-0.00000001 < b) && ( b < 0.00000001) ) { throw divide_by_zero("Divide by zero..."); //拋出異常,異常參數為自定義的異常類 } return a / b;}int main(int argc, char *argv[]){ try { cout<<Div(1, 0)<<endl; } catch(exception& e)//賦值兼容性原則,接收所有的異常類 { cout<<e.what()<<endl;//打印出字符串 } cout << "Press the enter key to continue ..."; cin.get(); return EXIT_SUCCESS;}

函數級try語法

可以將函數體作為一個完整的try語句塊。

如下圖所示: 這里寫圖片描述

函數級try語法可以更好將正常邏輯代碼與異常處理代碼分開,提高代碼的可讀性與維護性。

小結

異常處理是程序中隨處可見的情況。在工程實踐中,大多數的代碼都是用于處理異常的。異常處理的質量直接決定最終產品的質量。

C++提供了 throw語句 和 try…catch語句,用于將正常邏輯代碼與異常處理代碼進行分開處理。

catch(…)可以捕獲所有異常。 catch(…)經常作為最后一個catch語句出現。

不要在構造函數中拋出異常,這樣可能造成資源泄露。

工程中經常以標準庫中的異常類作為項目異常的基礎。

函數級try語句塊能夠更好的提高代碼的維護性。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 神农架林区| 嘉定区| 英超| 岗巴县| 乐亭县| 武邑县| 临夏县| 台江县| 庆元县| 静安区| 巫山县| 大化| 阿城市| 武宁县| 监利县| 莱西市| 分宜县| 库尔勒市| 福泉市| 崇阳县| SHOW| 阳谷县| 固安县| 铜梁县| 朝阳市| 南溪县| 裕民县| 来安县| 通江县| 莒南县| 赤水市| 化德县| 博野县| 东阳市| 抚顺县| 辽中县| 浦江县| 虹口区| 建昌县| 德兴市| 三原县|