![《C++程序設計語言》課件第13章_第1頁](http://file4.renrendoc.com/view6/M01/3B/01/wKhkGWd_anCAcCybAAO2lDrgtLY582.jpg)
![《C++程序設計語言》課件第13章_第2頁](http://file4.renrendoc.com/view6/M01/3B/01/wKhkGWd_anCAcCybAAO2lDrgtLY5822.jpg)
![《C++程序設計語言》課件第13章_第3頁](http://file4.renrendoc.com/view6/M01/3B/01/wKhkGWd_anCAcCybAAO2lDrgtLY5823.jpg)
![《C++程序設計語言》課件第13章_第4頁](http://file4.renrendoc.com/view6/M01/3B/01/wKhkGWd_anCAcCybAAO2lDrgtLY5824.jpg)
![《C++程序設計語言》課件第13章_第5頁](http://file4.renrendoc.com/view6/M01/3B/01/wKhkGWd_anCAcCybAAO2lDrgtLY5825.jpg)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第13章異常處理
13.1概述
13.2C++異常處理結構try、throw和catch
13.3異常類層次*13.4捕獲new操作所產生的異常*13.5C++標準庫異常層次
小結
練習題
本章要點:
C++異常處理結構;
C++異常類的層次化組織;
捕獲new產生的異常;
C++標準庫異常類層次。
13.1概述
正如7.3節(jié)所述,對于一個實用的程序而言,沒有錯誤處理是不可能的。實際的(大型)程序是由許多人在不同的時間內開發(fā)出來的,許多出錯處理任務并不一定能在(或者不應當在)發(fā)現(xiàn)出錯的地方完成。
一個欠缺良好結構的程序(有時也可能是由于沒有語言支持機制造成的),對其錯誤通常采用判斷語句(如C++中的if和switch語句)進行判斷與處理。這種錯誤的判斷與處理方式帶來兩個問題:
(1)大量的錯誤處理代碼與程序的功能代碼交織在一起,這不僅造成了程序結構的混亂不堪,而且往往錯誤處理代碼遠遠大于程序的功能代碼,這使得程序的可讀性與可維護性大大下降。
(2)對于某些錯誤而言,程序不知如何或不能夠處理,因而對此類錯誤只能丟棄,這又往往使程序的可靠性大大下降,甚至在某些極端的情況下,程序退化成不可用。
欲正確處理一個錯誤,需要明確知道如下兩類信息:
(1)錯誤發(fā)生的地點,何種類型的錯誤;
(2)怎樣處理錯誤,在何處處理錯誤。
因此,出錯處理任務應當被分解成兩部分:錯誤處理與錯誤的報告。
(1)在某處(更一般地說是在某一模塊)若發(fā)現(xiàn)錯誤(該錯誤可能是本模塊中的錯誤,亦可能是來自其它模塊中的錯誤),能處理,則進行處理。
(2)不能處理則應設置出錯報告的條件,當滿足條件時進行報告,以提供必要的信息,供可能進行錯誤處理的模塊進行錯誤處理。
C++的異常處理機制(ExceptionHandling)提供了一種結構化的、能有效地捕獲和處理各種類型的錯誤的機制。該機制將錯誤的報告與錯誤的處理顯式分離,并使得系統(tǒng)能從導致異常的錯誤中恢復,恢復的過程即執(zhí)行異常處理器(ExceptionHandler)。
13.2C++異常處理結構try、throw和catch
在C++中,每一個異常(Exception)都是一個錯誤類的實例,C++用try-catch塊進行異常的捕獲與處理,用throw語句進行錯誤的報告。
C++的異常處理結構如下:
//…
try{
//…可能出現(xiàn)異常的程序代碼
}
catch(Error1e1){
//…對異常類Error1對象e1的處理代碼
}
catch(Error2e2){
//…對異常類Error2對象e2的處理代碼
}
//…
編程時,程序員將可能產生異常的代碼放入try塊中,try塊后面是一個或多個catch塊(亦稱為catch子句或異常處理器)。每個catch塊捕獲和處理其參數(shù)表中指定的某種類別的異常。
C++語法規(guī)定:try塊允許嵌套,catch塊不允許嵌套,且每個catch塊是互斥的。
當try塊中拋出異常時,程序控制離開try塊,并依次從catch塊中搜索其參數(shù)類型與異常類型相匹配的異常處理器進行異常處理,之后轉入到最后一個catch塊后的代碼執(zhí)行;如果try塊沒有拋出異常,則跳過所有的catch異常處理器,并轉入到最后一個catch塊后的代碼執(zhí)行。13.2.1拋出異常
在程序中,若出現(xiàn)某一異常,而在此時又無法進行自身處理,可利用throw子句重新拋出該異常。執(zhí)行throw的點稱為拋出點(ThrowPoint)。throw既可以拋出一個字符串字面值(錯誤消息),亦可以拋出一異常類對象。拋出對象向處理該異常的異常處理器傳遞錯誤信息。下面給出一try-catch和throw的應用實例。13.2.2重新拋出異常
捕獲異常的處理器(catch塊)當捕獲到一異常時,可能在某些情況下又不能處理該異常或不知如何處理該異?;虿荒芡耆幚碓摦惓#藭r,可利用throw語句重新拋出該異常,此時拋出的異常由其它異常處理器或系統(tǒng)進行處理。
例:
voidf()
{
try{
//...
}
catch(Ee){
//...
throw;
}
}13.2.3捕獲所有的異常
為了捕獲所有的異常,C++提供了catch()異常處理器以供處理系統(tǒng)中所有的catch塊沒有捕獲和處理的異常。
例:
voidm(){
try{
//...
}
catch(...){ //任意異常處理器
//...
}
}
13.3異?常?類?層?次
如果系統(tǒng)中可能有多個異常,而且這些異常是相關的,那么我們就應當將這些相關的異常類進行層次化的組織(采用繼承機制,樹或有向無環(huán)圖)。異常類的層次化組織對于正確捕獲和處理異常是至關重要的。
例如,在算術運算中可能產生下述異常:
classMatherr{//...};//通用算術異常類的父類
classOverflow:publicMatherr{//...};
//上溢異常類
classUnderflow:publicMatherr{//...};
//下溢異常類
classZerodivid:publicMatherr{//...};
//被零除異常類上述異常類可按上述形式進行組織,即Matherr為所有算術類的父類,其它的Overflow、Underflow和Zerodivid類均為Matherr類的子類。異常處理器可按如下方式進行組織:
//...
try{
//...
}
catch(Overflow){//上溢錯誤類的捕獲與處理
//...
}
catch(Underflow){//下溢錯誤類的捕獲與處理
//...
}
catch(Zerodivid){//被零除錯誤類的捕獲與處理
//...
}
catch(Matherr){//其它算術類錯誤的捕獲與處理
//...
}
//...從上述例子可看出,異常處理器的排列順序是按照異常類層次自底向上順序進行的,這樣才能保證當一個具體的或一般的算術類錯誤拋出時,其異常都確保能被捕獲處理。
catch異常處理器的參數(shù)類型可以是錯誤類層次中的父類類型,此時,若實參為子類,則參數(shù)只接受其父類成員的那一部分。當catch參數(shù)表中的參數(shù)為異常類的父類的指針或引用時,實參既可以是父類的指針或引用,亦可以是子類的指針或引用,此時即可進行多態(tài)的錯誤處理。*13.4捕獲new操作所產生的異常
從前面的討論我們已經(jīng)知道,new操作用于動態(tài)地在堆中申請內存。當new操作失敗(返回值為零)時,我們可用如下方法處理該異常:
(1)采用assert宏測試new的返回值,若返回值為零,則assert宏終止程序的運行。但這并不是new異常處理的健壯機制,因為它不允許我們用任何方法從異常中恢復。
(2)?C++標準指出:當出現(xiàn)new故障時,系統(tǒng)會拋出bad_alloc異常(在頭文件<new>中定義),我們可利用該異常和C++的異常處理機制來處理該異常。例如:
(3)利用函數(shù)set_new_handler(void(*fp)())(在<new>中定義)進行new故障的處理,其中fp為指向一用戶編寫的處理該new故障的函數(shù)指針。當new故障發(fā)生時(不管在程序中的任何地方),系統(tǒng)通過set_new_handler函數(shù)自動跳轉到fp指針所指的new故障的異常處理函數(shù)中。例如:
#include<iostream>
#include<new>
#include<cstdlib>
usingnamespacestd;
voidcustomNewHandler()
{
cerr<<“customNewHandlerwascalled”;
abort();
(4)一般而言,我們用new操作符動態(tài)申請內存空間,用delete操作符釋放其動態(tài)申請的內存空間。但當內存分配之后且在執(zhí)行delete之前發(fā)生了異常,則可能發(fā)生內存泄漏問題。解決該問題的方法是采用系統(tǒng)頭文件<memery>中的auto_ptr類模板。
一個auto_ptr對象維護動態(tài)分配的內存指針,當該auto_ptr對象超出作用域時,則auto_ptr自動進行delete操作。auto_ptr類模板過載了“*”和“->”運算符,因此對auto_ptr可像一個普通指針一樣使用。auto_ptr類模板及其使用方法見下例:程序運行輸出結果:
Creatinganauto_ptrobjectthatpointstoanInteger
ConstructorforInteger7
Usingtheauto_ptrtomanipulatetheInteger
IntegeraftersetInteger:99
Terminatingprogram
DestructorforInteger99*13.5C++?標準庫異常層次
C++標準庫提供的異常類層次中,所有的異常類都從exception(在<exception>中定義)派生而來,該基類有一個成員函數(shù)what(),每個派生異常類可重置該方法,該方法報告異常的相應信息。
從exception類可直接派生兩個異常類:
runtime_error類,所有運行時異常類的父類;
logic_error類,所有程序邏輯錯誤類的父類。
另外,從exception中還可以派生出一些其它的異常類(系統(tǒng)運行時自動拋出),如:
bad_alloc,new操作失敗拋出的異常;
bad_cast,dynamic_cast操作失效拋出的異常;
bad_typeid,type_id操作失效時拋出的異常。小結
C++?的異常處理機制使得程序可結構化地捕獲和處理異常,而不是任其發(fā)生和造成惡果。
每一個異常即是一個錯誤類的實例。C++用try-catch結構來捕獲和處理程序所發(fā)生的異常。每個catch是互斥的,catch子句的參數(shù)為一個異常類對象或異常類的指針或引用,或者為char*類型。每個catch捕獲并處理與其參數(shù)表一致或相容的異常對象。一般而言,系統(tǒng)中有多種類別的異常,我們應將這些異常進行層次化的組織。為了捕獲和處理整個異常類層次中的所有異常,catch應以其參數(shù)類別按異常類層次自底向上的順序進行排列。我們還可用catch(…)來捕獲一切未知的異常。
當程序中出現(xiàn)異常而又無法處理或不知如何處理時,可用throw子句重新拋出該異常;當catch處理器接到一個異常而又無法處理或不知如何處理時,可用throw重新拋出該異常。
C++標準類庫中,定義了except
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 裝修進度款支付合同
- 藥品冷鏈運輸保密合同
- 商業(yè)空間裝修施工合同范本
- 包包購銷合同
- 咨詢服務合同終止協(xié)議書年
- 互聯(lián)網(wǎng)廣告投放策略與實踐案例
- 建筑項目居間合同
- 出租打印機合同年
- 圖書購銷合同范例
- 工程管理咨詢合同
- 血透失衡綜合征的護理課件
- 2023年中國社會科學評價研究院第一批專業(yè)技術人員招聘2人筆試參考題庫(共500題)答案詳解版
- CBCC中國建筑色卡色
- 建設工程項目法律風險防控培訓稿PPT講座
- GB/T 4745-2012紡織品防水性能的檢測和評價沾水法
- 軟件需求調研表-修改版
- 山東省中考物理總復習 八上 第1講 機械運動
- 北京理工大學應用光學課件(大全)李林
- 國家綜合性消防救援隊伍消防員管理規(guī)定
- 河南省三門峽市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會明細
- 五年級上冊數(shù)學習題課件 簡便計算專項整理 蘇教版 共21張
評論
0/150
提交評論