第12章 異常處理_第1頁
第12章 異常處理_第2頁
第12章 異常處理_第3頁
第12章 異常處理_第4頁
第12章 異常處理_第5頁
已閱讀5頁,還剩25頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第十二章異常處理,清華大學鄭莉,目錄,12.1異常處理的基本思想12.2C+異常處理的實現(xiàn)12.3異常處理中的構(gòu)造與析構(gòu)12.4標準程序庫異常處理12.5綜合實例對個人銀行賬戶管理程序的改進12.6深度探索12.7小結(jié),2,12.1異常處理的基本思想,3,12.2.1異常處理的語法,4,12.2C+異常處理的實現(xiàn),拋擲異常的程序段.throw表達式;.,捕獲并處理異常的程序段try復合語句catch(異常聲明)復合語句catch(異常聲明)復合語句,保護段,異常處理程序,12.2.1異常處理的語法(續(xù)),若有異常則通過throw操作創(chuàng)建一個異常對象并拋擲。將可能拋出異常的程序段嵌在try塊之中??刂仆ㄟ^正常的順序執(zhí)行到達try語句,然后執(zhí)行try塊內(nèi)的保護段。如果在保護段執(zhí)行期間沒有引起異常,那么跟在try塊后的catch子句就不執(zhí)行。程序從try塊后跟隨的最后一個catch子句后面的語句繼續(xù)執(zhí)行下去。catch子句按其在try塊后出現(xiàn)的順序被檢查。匹配的catch子句將捕獲并處理異常(或繼續(xù)拋擲異常)。如果匹配的處理器未找到,則運行庫函數(shù)terminate將被自動調(diào)用,其缺省功能是調(diào)用abort終止程序。,5,12.2C+異常處理的實現(xiàn),例12-1處理除零異常,/12_1.cpp#includeusingnamespacestd;intdivide(intx,inty)if(y=0)throwx;returnx/y;intmain()trycout5/2=divide(5,2)endl;cout8/0=divide(8,0)endl;cout7/1=divide(7,1)endl;catch(inte)couteisdividedbyzero!endl;coutThatisok.endl;return0;,6,12.2C+異常處理的實現(xiàn)12.2.1異常處理的語法,結(jié)果如下:5/2=28isdividedbyzero!Thatisok.,12.2.2異常接口聲明,可以在函數(shù)的聲明中列出這個函數(shù)可能拋擲的所有異常類型。例如:voidfun()throw(A,B,C,D);若無異常接口聲明,則此函數(shù)可以拋擲任何類型的異常。不拋擲任何類型異常的函數(shù)聲明如下:voidfun()throw();,7,12.2C+異常處理的實現(xiàn),12.3異常處理中的構(gòu)造與析構(gòu),找到一個匹配的catch異常處理后初始化異常參數(shù)。將從對應(yīng)的try塊開始到異常被拋擲處之間構(gòu)造(且尚未析構(gòu))的所有自動對象進行析構(gòu)。從最后一個catch處理之后開始恢復執(zhí)行。,8,例12-2使用帶析構(gòu)語義的類的C+異常處理,/12_2.cpp#include#includeusingnamespacestd;classMyExceptionpublic:MyException(conststring,9,12.3異常處理中的構(gòu)造與析構(gòu),voidfunc()throw(MyException)Demod;coutThrowMyExceptioninfunc()endl;throwMyException(exceptionthrownbyfunc();intmain()coutInmainfunctionendl;tryfunc();catch(MyException,10,例12-2(續(xù)),12.3異常處理中的構(gòu)造與析構(gòu),例12-2(續(xù)),結(jié)果如下:InmainfunctionConstructorofDemoThrowMyExceptioninfunc()DestructorofDemoCaughtanexception:exceptionthrownbyfunc()Resumetheexecutionofmain(),11,12.3異常處理中的構(gòu)造與析構(gòu),12.4標準程序庫異常處理,12,標準程序庫的異常類,exception:標準程序庫異常類的公共基類logic_error表示可以在程序中被預先檢測到的異常如果小心地編寫程序,這類異常能夠避免runtime_error表示難以被預先檢測的異常,13,12.4標準程序庫異常處理,例12-3三角形面積計算,編寫一個計算三角形面積的函數(shù),函數(shù)的參數(shù)為三角形三邊邊長a、b、c,可以用Heron公式計算:設(shè),則三角形面積,14,12.4標準程序庫異常處理,例12-3(續(xù)),/12_3.cpp#include#include#includeusingnamespacestd;/給出三角形三邊長,計算三角形面積doublearea(doublea,doubleb,doublec)throw(invalid_argument)/判斷三角形邊長是否為正if(a=0|b=0|c=0)throwinvalid_argument(thesidelengthshouldbepositive);/判斷三邊長是否滿足三角不等式if(a+b=c|b+cbc;trydoubles=area(a,b,c);/嘗試計算三角形面積coutArea:sendl;catch(exception,16,12.4標準程序庫異常處理,例12-3(續(xù)),運行結(jié)果1:Pleaseinputthesidelengthsofatriangle:345Area:6運行結(jié)果2:Pleaseinputthesidelengthsofatriangle:055Error:thesidelengthshouldbepositive運行結(jié)果2:Pleaseinputthesidelengthsofatriangle:124Error:thesidelengthshouldfitthetriangleinequation,17,12.4標準程序庫異常處理,12.5綜合實例對個人銀行賬戶管理程序的改進,本例中,在構(gòu)造或輸入一個Date對象時如發(fā)生了錯誤,直接使用標準程序庫中的runtime_error構(gòu)造異常并拋出;在賬戶類中如發(fā)生了錯誤,由于希望異常信息能夠標識是哪個賬戶發(fā)生了錯誤。本程序中創(chuàng)建了一個類AccountException,該類從runtime_error派生,該類中保存了一個Account型常指針,指向發(fā)生錯誤的賬戶,這樣在主函數(shù)中,輸出錯誤信息的同時也可以將賬號輸出。,18,/date.cpp,僅列出與以前不同的內(nèi)容,下同#includedate.h#include#includeusingnamespacestd;Date:Date(intyear,intmonth,intday):year(year),month(month),day(day)if(daygetMaxDay()throwruntime_error(Invaliddate);intyears=year-1;totalDays=years*365+years/4-years/100+years/400+DAYS_BEFORE_MONTHmonth-1+day;if(isLeapYear(),19,12.5綜合實例對個人銀行賬戶管理程序的改進,例12-4,/account.h#ifndef_ACCOUNT_H_#define_ACCOUNT_H_#includedate.h#includeaccumulator.h#include#include#include#include/account.h中增加了以下類,其它各類的定義與例11-13完全相同,不再重復給出classAccountException:publicstd:runtime_errorprivate:constAccount*account;public:AccountException(constAccount*account,conststd:string#endif/_ACCOUNT_H_,20,12.5綜合實例對個人銀行賬戶管理程序的改進,例12-4(續(xù)),/account.cpp中僅以下成員函數(shù)的實現(xiàn)與例11-13不同,其它內(nèi)容皆與之完全相同voidAccount:error(conststring/關(guān)閉文件,21,12.5綜合實例對個人銀行賬戶管理程序的改進,例12-4(續(xù)),ofstreamfileOut(FILE_NAME,ios_base:app);/以追加模式cout;stringcmdLine;getline(cin,cmdLine);tryif(controller.runCommand(cmdLine)fileOutgetId():e.what()w21500buyatelevision2009-1-1#C5392394-1500-1550buyatelevision2009-1-1Total:18982.9commandq2008-12-52009-1-32Error:Invaliddate2009-1-1Total:18982.9commandq2008-12-52009-1-312008-12-5#S3755217550010500salary2009-1-1#S375521717.7710517.8interest2009-1-1#0234234215.1610015.2interest2009-1-1#C5392394-50-50annualfee2009-1-1#C5392394-1500-1550buyatelevision2009-1-1Total:18982.9commande,23,12.5綜合實例對個人銀行賬戶管理程序的改進,12.6.1異常安全性問題,一個異常安全的函數(shù),在有異常拋出時:不應(yīng)泄露任何資源不能使任何對象進入非法狀態(tài)反例:例9-8中的下列代碼:templatevoidStack:push(constT/將新元素壓入棧頂如果賦值過程中有異常拋出,由于top已經(jīng)增1,棧頂?shù)膬?nèi)容將變得不確定。,24,12.6深度探索,12.6.1異常安全性問題(續(xù)),該函數(shù)的修正版本:templatevoidStack:push(constT即使賦值時拋出異常,由于此時top并沒有真正增1,因此當前對象的狀態(tài)沒有改變,該函數(shù)是異常安全的。,25,12.6深度探索,編寫異常安全程序的原則,明確哪些操作絕對不會拋擲異常這些操作是異常安全編程的基石例:基本數(shù)據(jù)類型的絕大部分操作,針的賦值、算術(shù)運算和比較運算,STL容器的swap函數(shù)盡量確保析構(gòu)函數(shù)不拋擲異常,26,12.6深度探索12.6.1異常安全性問題,12.6.2避免異常發(fā)生時的資源泄漏,一個函數(shù),必須在有異常向外拋出前,釋放應(yīng)由它負責釋放的資源。通常的解決方案把一切動態(tài)分配的資源都包裝成棧上的對象,利用拋擲異常時自動調(diào)用對象析構(gòu)函數(shù)的特性來釋放資源。對于必須在堆上構(gòu)造的對象,可以用智能指針auto_ptr加以包裝。,27,12.6深度探索,智能指針auto_ptr,C+標準庫的一個類模板在memory頭文件中定義有一個類型參數(shù)X,表示智能指針指向數(shù)據(jù)的類型每個智能指針對象關(guān)聯(lián)一個普通指針構(gòu)造函數(shù):explicitauto_ptr(X*p=0)throw();獲得與智能指針對象關(guān)聯(lián)的指針:X*get()constthrow();由于auto_ptr的“*”與“-”運算符已被重載,對一個auto_ptr的對象使用“*”和“-”,等價于對它所關(guān)聯(lián)的指針使用相應(yīng)運算符。,28,12

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論