版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第13章異常處理
13.1概述
13.2C++異常處理結(jié)構(gòu)try、throw和catch
13.3異常類層次*13.4捕獲new操作所產(chǎn)生的異常*13.5C++標(biāo)準(zhǔn)庫異常層次
小結(jié)
練習(xí)題
本章要點:
C++異常處理結(jié)構(gòu);
C++異常類的層次化組織;
捕獲new產(chǎn)生的異常;
C++標(biāo)準(zhǔn)庫異常類層次。
13.1概述
正如7.3節(jié)所述,對于一個實用的程序而言,沒有錯誤處理是不可能的。實際的(大型)程序是由許多人在不同的時間內(nèi)開發(fā)出來的,許多出錯處理任務(wù)并不一定能在(或者不應(yīng)當(dāng)在)發(fā)現(xiàn)出錯的地方完成。
一個欠缺良好結(jié)構(gòu)的程序(有時也可能是由于沒有語言支持機制造成的),對其錯誤通常采用判斷語句(如C++中的if和switch語句)進行判斷與處理。這種錯誤的判斷與處理方式帶來兩個問題:
(1)大量的錯誤處理代碼與程序的功能代碼交織在一起,這不僅造成了程序結(jié)構(gòu)的混亂不堪,而且往往錯誤處理代碼遠遠大于程序的功能代碼,這使得程序的可讀性與可維護性大大下降。
(2)對于某些錯誤而言,程序不知如何或不能夠處理,因而對此類錯誤只能丟棄,這又往往使程序的可靠性大大下降,甚至在某些極端的情況下,程序退化成不可用。
欲正確處理一個錯誤,需要明確知道如下兩類信息:
(1)錯誤發(fā)生的地點,何種類型的錯誤;
(2)怎樣處理錯誤,在何處處理錯誤。
因此,出錯處理任務(wù)應(yīng)當(dāng)被分解成兩部分:錯誤處理與錯誤的報告。
(1)在某處(更一般地說是在某一模塊)若發(fā)現(xiàn)錯誤(該錯誤可能是本模塊中的錯誤,亦可能是來自其它模塊中的錯誤),能處理,則進行處理。
(2)不能處理則應(yīng)設(shè)置出錯報告的條件,當(dāng)滿足條件時進行報告,以提供必要的信息,供可能進行錯誤處理的模塊進行錯誤處理。
C++的異常處理機制(ExceptionHandling)提供了一種結(jié)構(gòu)化的、能有效地捕獲和處理各種類型的錯誤的機制。該機制將錯誤的報告與錯誤的處理顯式分離,并使得系統(tǒng)能從導(dǎo)致異常的錯誤中恢復(fù),恢復(fù)的過程即執(zhí)行異常處理器(ExceptionHandler)。
13.2C++異常處理結(jié)構(gòu)try、throw和catch
在C++中,每一個異常(Exception)都是一個錯誤類的實例,C++用try-catch塊進行異常的捕獲與處理,用throw語句進行錯誤的報告。
C++的異常處理結(jié)構(gòu)如下:
//…
try{
//…可能出現(xiàn)異常的程序代碼
}
catch(Error1e1){
//…對異常類Error1對象e1的處理代碼
}
catch(Error2e2){
//…對異常類Error2對象e2的處理代碼
}
//…
編程時,程序員將可能產(chǎn)生異常的代碼放入try塊中,try塊后面是一個或多個catch塊(亦稱為catch子句或異常處理器)。每個catch塊捕獲和處理其參數(shù)表中指定的某種類別的異常。
C++語法規(guī)定:try塊允許嵌套,catch塊不允許嵌套,且每個catch塊是互斥的。
當(dāng)try塊中拋出異常時,程序控制離開try塊,并依次從catch塊中搜索其參數(shù)類型與異常類型相匹配的異常處理器進行異常處理,之后轉(zhuǎn)入到最后一個catch塊后的代碼執(zhí)行;如果try塊沒有拋出異常,則跳過所有的catch異常處理器,并轉(zhuǎn)入到最后一個catch塊后的代碼執(zhí)行。13.2.1拋出異常
在程序中,若出現(xiàn)某一異常,而在此時又無法進行自身處理,可利用throw子句重新拋出該異常。執(zhí)行throw的點稱為拋出點(ThrowPoint)。throw既可以拋出一個字符串字面值(錯誤消息),亦可以拋出一異常類對象。拋出對象向處理該異常的異常處理器傳遞錯誤信息。下面給出一try-catch和throw的應(yīng)用實例。13.2.2重新拋出異常
捕獲異常的處理器(catch塊)當(dāng)捕獲到一異常時,可能在某些情況下又不能處理該異?;虿恢绾翁幚碓摦惓;虿荒芡耆幚碓摦惓?,此時,可利用throw語句重新拋出該異常,此時拋出的異常由其它異常處理器或系統(tǒng)進行處理。
例:
voidf()
{
try{
//...
}
catch(Ee){
//...
throw;
}
}13.2.3捕獲所有的異常
為了捕獲所有的異常,C++提供了catch()異常處理器以供處理系統(tǒng)中所有的catch塊沒有捕獲和處理的異常。
例:
voidm(){
try{
//...
}
catch(...){ //任意異常處理器
//...
}
}
13.3異?常?類?層?次
如果系統(tǒng)中可能有多個異常,而且這些異常是相關(guān)的,那么我們就應(yīng)當(dāng)將這些相關(guān)的異常類進行層次化的組織(采用繼承機制,樹或有向無環(huán)圖)。異常類的層次化組織對于正確捕獲和處理異常是至關(guān)重要的。
例如,在算術(shù)運算中可能產(chǎn)生下述異常:
classMatherr{//...};//通用算術(shù)異常類的父類
classOverflow:publicMatherr{//...};
//上溢異常類
classUnderflow:publicMatherr{//...};
//下溢異常類
classZerodivid:publicMatherr{//...};
//被零除異常類上述異常類可按上述形式進行組織,即Matherr為所有算術(shù)類的父類,其它的Overflow、Underflow和Zerodivid類均為Matherr類的子類。異常處理器可按如下方式進行組織:
//...
try{
//...
}
catch(Overflow){//上溢錯誤類的捕獲與處理
//...
}
catch(Underflow){//下溢錯誤類的捕獲與處理
//...
}
catch(Zerodivid){//被零除錯誤類的捕獲與處理
//...
}
catch(Matherr){//其它算術(shù)類錯誤的捕獲與處理
//...
}
//...從上述例子可看出,異常處理器的排列順序是按照異常類層次自底向上順序進行的,這樣才能保證當(dāng)一個具體的或一般的算術(shù)類錯誤拋出時,其異常都確保能被捕獲處理。
catch異常處理器的參數(shù)類型可以是錯誤類層次中的父類類型,此時,若實參為子類,則參數(shù)只接受其父類成員的那一部分。當(dāng)catch參數(shù)表中的參數(shù)為異常類的父類的指針或引用時,實參既可以是父類的指針或引用,亦可以是子類的指針或引用,此時即可進行多態(tài)的錯誤處理。*13.4捕獲new操作所產(chǎn)生的異常
從前面的討論我們已經(jīng)知道,new操作用于動態(tài)地在堆中申請內(nèi)存。當(dāng)new操作失敗(返回值為零)時,我們可用如下方法處理該異常:
(1)采用assert宏測試new的返回值,若返回值為零,則assert宏終止程序的運行。但這并不是new異常處理的健壯機制,因為它不允許我們用任何方法從異常中恢復(fù)。
(2)?C++標(biāo)準(zhǔn)指出:當(dāng)出現(xiàn)new故障時,系統(tǒng)會拋出bad_alloc異常(在頭文件<new>中定義),我們可利用該異常和C++的異常處理機制來處理該異常。例如:
(3)利用函數(shù)set_new_handler(void(*fp)())(在<new>中定義)進行new故障的處理,其中fp為指向一用戶編寫的處理該new故障的函數(shù)指針。當(dāng)new故障發(fā)生時(不管在程序中的任何地方),系統(tǒng)通過set_new_handler函數(shù)自動跳轉(zhuǎn)到fp指針?biāo)傅膎ew故障的異常處理函數(shù)中。例如:
#include<iostream>
#include<new>
#include<cstdlib>
usingnamespacestd;
voidcustomNewHandler()
{
cerr<<“customNewHandlerwascalled”;
abort();
(4)一般而言,我們用new操作符動態(tài)申請內(nèi)存空間,用delete操作符釋放其動態(tài)申請的內(nèi)存空間。但當(dāng)內(nèi)存分配之后且在執(zhí)行delete之前發(fā)生了異常,則可能發(fā)生內(nèi)存泄漏問題。解決該問題的方法是采用系統(tǒng)頭文件<memery>中的auto_ptr類模板。
一個auto_ptr對象維護動態(tài)分配的內(nèi)存指針,當(dāng)該auto_ptr對象超出作用域時,則auto_ptr自動進行delete操作。auto_ptr類模板過載了“*”和“->”運算符,因此對auto_ptr可像一個普通指針一樣使用。auto_ptr類模板及其使用方法見下例:程序運行輸出結(jié)果:
Creatinganauto_ptrobjectthatpointstoanInteger
ConstructorforInteger7
Usingtheauto_ptrtomanipulatetheInteger
IntegeraftersetInteger:99
Terminatingprogram
DestructorforInteger99*13.5C++?標(biāo)準(zhǔn)庫異常層次
C++標(biāo)準(zhǔn)庫提供的異常類層次中,所有的異常類都從exception(在<exception>中定義)派生而來,該基類有一個成員函數(shù)what(),每個派生異常類可重置該方法,該方法報告異常的相應(yīng)信息。
從exception類可直接派生兩個異常類:
runtime_error類,所有運行時異常類的父類;
logic_error類,所有程序邏輯錯誤類的父類。
另外,從exception中還可以派生出一些其它的異常類(系統(tǒng)運行時自動拋出),如:
bad_alloc,new操作失敗拋出的異常;
bad_cast,dynamic_cast操作失效拋出的異常;
bad_typeid,type_id操作失效時拋出的異常。小結(jié)
C++?的異常處理機制使得程序可結(jié)構(gòu)化地捕獲和處理異常,而不是任其發(fā)生和造成惡果。
每一個異常即是一個錯誤類的實例。C++用try-catch結(jié)構(gòu)來捕獲和處理程序所發(fā)生的異常。每個catch是互斥的,catch子句的參數(shù)為一個異常類對象或異常類的指針或引用,或者為char*類型。每個catch捕獲并處理與其參數(shù)表一致或相容的異常對象。一般而言,系統(tǒng)中有多種類別的異常,我們應(yīng)將這些異常進行層次化的組織。為了捕獲和處理整個異常類層次中的所有異常,catch應(yīng)以其參數(shù)類別按異常類層次自底向上的順序進行排列。我們還可用catch(…)來捕獲一切未知的異常。
當(dāng)程序中出現(xiàn)異常而又無法處理或不知如何處理時,可用throw子句重新拋出該異常;當(dāng)catch處理器接到一個異常而又無法處理或不知如何處理時,可用throw重新拋出該異常。
C++標(biāo)準(zhǔn)類庫中,定義了except
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025標(biāo)準(zhǔn)蔬菜買賣合同范本
- 2025施工現(xiàn)場環(huán)境職業(yè)健康安全管理合同書
- 2025年度教育機構(gòu)辦學(xué)許可證轉(zhuǎn)讓及人才培養(yǎng)合作合同3篇
- 2025年度農(nóng)村小型水庫防洪減災(zāi)能力提升承包合同
- 2025年度國土綠化行動-鄉(xiāng)土樹苗采購與生態(tài)修復(fù)合同
- 二零二五年度排水溝清理與排水設(shè)施智能化改造協(xié)議3篇
- 二零二五年度創(chuàng)意辦公場地租賃與設(shè)計合同3篇
- 二零二五年度農(nóng)機租賃與農(nóng)業(yè)廢棄物綜合利用合作合同2篇
- 2025工廠生產(chǎn)承包合同樣本
- 2025年度公廁節(jié)能照明系統(tǒng)承包施工合同范本3篇
- 陳赫賈玲小品《歡喜密探》臺詞劇本
- 測角儀規(guī)范要求
- 腦出血入院病歷
- 數(shù)字孿生智慧水利建設(shè)方案
- 焊接工藝流程圖
- 風(fēng)機基礎(chǔ)大體積混凝土澆筑專項施工方案
- 2023-2024學(xué)年北京市海淀區(qū)六年級數(shù)學(xué)第一學(xué)期期末達標(biāo)檢測試題含答案
- 中國古代文學(xué)史PPT完整PPT完整全套教學(xué)課件
- (完整版)人教版高中物理新舊教材知識對比
- 最好用高速公路機電維修手冊
- 土默特右旗高源礦業(yè)有限責(zé)任公司高源煤礦2022年度礦山地質(zhì)環(huán)境年度治理計劃
評論
0/150
提交評論