




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第7章 異常處理 寫函數(shù)庫的程序員可以檢測到庫函數(shù)運(yùn)行時(shí)的錯(cuò)誤(如數(shù)寫函數(shù)庫的程序員可以檢測到庫函數(shù)運(yùn)行時(shí)的錯(cuò)誤(如數(shù)組訪問越界),但通常卻不知道應(yīng)該如何處理這些錯(cuò)誤組訪問越界),但通常卻不知道應(yīng)該如何處理這些錯(cuò)誤 異常處理的基本想法是,讓一個(gè)函數(shù)在發(fā)現(xiàn)了自己無法處異常處理的基本想法是,讓一個(gè)函數(shù)在發(fā)現(xiàn)了自己無法處理的錯(cuò)誤時(shí)拋出一個(gè)異常,希望它的(直接或間接)調(diào)用理的錯(cuò)誤時(shí)拋出一個(gè)異常,希望它的(直接或間接)調(diào)用者能夠處理這個(gè)問題。者能夠處理這個(gè)問題。異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說明程序邏輯經(jīng)常對決定程序下一步怎樣執(zhí)行的條件進(jìn)行測試程序邏輯經(jīng)
2、常對決定程序下一步怎樣執(zhí)行的條件進(jìn)行測試執(zhí)行一個(gè)任務(wù)如果這個(gè)任務(wù)沒有正確執(zhí)行 則執(zhí)行錯(cuò)誤處理執(zhí)行下一個(gè)任務(wù)如果該任務(wù)沒有正確執(zhí)行 則執(zhí)行錯(cuò)誤處理傳統(tǒng)錯(cuò)誤處理方法 可以處理的錯(cuò)誤在發(fā)生錯(cuò)誤的地方就地處理可以處理的錯(cuò)誤在發(fā)生錯(cuò)誤的地方就地處理 在檢查到一個(gè)在局部無法處理的問題時(shí),一個(gè)函數(shù)可以:在檢查到一個(gè)在局部無法處理的問題時(shí),一個(gè)函數(shù)可以: 終止程序終止程序 abort() /exit() 返回一個(gè)表示返回一個(gè)表示“錯(cuò)誤錯(cuò)誤”的值。的值。int 返回一個(gè)合法值,讓程序處于某種非法的狀態(tài)返回一個(gè)合法值,讓程序處于某種非法的狀態(tài)。errno 調(diào)用一個(gè)預(yù)先準(zhǔn)備好在出現(xiàn)調(diào)用一個(gè)預(yù)先準(zhǔn)備好在出現(xiàn)“錯(cuò)誤錯(cuò)誤
3、”的情況下用的函數(shù)。的情況下用的函數(shù)。處理錯(cuò)誤的傳統(tǒng)方法 處理錯(cuò)誤的傳統(tǒng)方法:錯(cuò)誤處理代碼是在整個(gè)系統(tǒng)代碼中分處理錯(cuò)誤的傳統(tǒng)方法:錯(cuò)誤處理代碼是在整個(gè)系統(tǒng)代碼中分布的。代碼中可能出錯(cuò)的地方都要布的。代碼中可能出錯(cuò)的地方都要當(dāng)場進(jìn)行當(dāng)場進(jìn)行錯(cuò)誤處理。在寫錯(cuò)誤處理。在寫程序時(shí),必須知道所有的錯(cuò)誤該如何處理程序時(shí),必須知道所有的錯(cuò)誤該如何處理 好處好處: 程序員閱讀代碼時(shí)能夠程序員閱讀代碼時(shí)能夠直接直接看到錯(cuò)誤處理情況,確看到錯(cuò)誤處理情況,確定是否實(shí)現(xiàn)了正確的錯(cuò)誤檢查。定是否實(shí)現(xiàn)了正確的錯(cuò)誤檢查。 問題問題: 代碼中受到錯(cuò)誤處理的代碼中受到錯(cuò)誤處理的“污染污染”,使應(yīng)用程序本身使應(yīng)用程序本身的代碼更
4、加晦澀難懂,難以看出代碼功能是否正確實(shí)現(xiàn)。的代碼更加晦澀難懂,難以看出代碼功能是否正確實(shí)現(xiàn)。這樣就使代碼的這樣就使代碼的理解和維護(hù)更加困難理解和維護(hù)更加困難。面向?qū)ο笾械漠惓L幚?面向?qū)ο笾?,程序員經(jīng)常做的是一些工具(類的設(shè)計(jì)面向?qū)ο笾?,程序員經(jīng)常做的是一些工具(類的設(shè)計(jì)與實(shí)現(xiàn))與實(shí)現(xiàn)) 這些工具能夠檢測出錯(cuò)誤,但往往不知道該如何處理這些工具能夠檢測出錯(cuò)誤,但往往不知道該如何處理錯(cuò)誤。錯(cuò)誤的處理是由工具的使用者決定錯(cuò)誤。錯(cuò)誤的處理是由工具的使用者決定 需要一種機(jī)制能將檢測到的錯(cuò)誤告訴使用者需要一種機(jī)制能將檢測到的錯(cuò)誤告訴使用者異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異
5、常 異常規(guī)格說明8異常處理的基本思想函數(shù)f()捕獲并處理異常函數(shù)h() 引發(fā)異常函數(shù)g()調(diào)用者異常傳播方向調(diào)用關(guān)系異常處理 C+的新異常處理特性:的新異常處理特性: 異常處理將異常處理將檢測發(fā)現(xiàn)檢測發(fā)現(xiàn)錯(cuò)誤的代碼與錯(cuò)誤的代碼與處理處理錯(cuò)誤的代碼分錯(cuò)誤的代碼分開來。程序員的工作也可做相應(yīng)分工(例如,庫函數(shù)開來。程序員的工作也可做相應(yīng)分工(例如,庫函數(shù)程序員負(fù)責(zé)檢測異常,而調(diào)用庫函數(shù)的另一程序員則程序員負(fù)責(zé)檢測異常,而調(diào)用庫函數(shù)的另一程序員則負(fù)責(zé)捕獲與處理異常)。負(fù)責(zé)捕獲與處理異常)。 使程序員可以刪除程序執(zhí)行使程序員可以刪除程序執(zhí)行“主線條主線條”中的錯(cuò)誤處理中的錯(cuò)誤處理代碼,從而提高程序的可
6、讀性和可維護(hù)性。代碼,從而提高程序的可讀性和可維護(hù)性。異常處理基礎(chǔ)簡介 如果某段程序可能會(huì)拋出異常,則必須通知系統(tǒng)啟動(dòng)如果某段程序可能會(huì)拋出異常,則必須通知系統(tǒng)啟動(dòng)異常處理機(jī)制。即通過異常處理機(jī)制。即通過try語句塊實(shí)現(xiàn)。語句塊實(shí)現(xiàn)。 異常處理代碼的一般形式:異常處理代碼的一般形式:try可能拋出異常的代碼 catch(類型1 參數(shù)1) 處理該異常的代碼 catch(類型2 參數(shù)2) 處理該異常的代碼 Try語句塊中包含了可能拋出異常的代碼,一旦拋出了異常,則退出try語句塊,進(jìn)入try后面的異常捕獲和處理異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說明拋出
7、異常 如果程序發(fā)生異常情況,而在當(dāng)前的環(huán)境中獲取不到異常處理如果程序發(fā)生異常情況,而在當(dāng)前的環(huán)境中獲取不到異常處理的足夠信息,我們可以的足夠信息,我們可以創(chuàng)建一包含出錯(cuò)信息的對象并將該對象并將該對象拋出當(dāng)前環(huán)境,發(fā)送給更大的環(huán)境中。這稱為異常拋出。拋出當(dāng)前環(huán)境,發(fā)送給更大的環(huán)境中。這稱為異常拋出。 例1 throw myerror(“something bad happened”); myerror是一個(gè)類,它以字符串變量為參數(shù) 例2 throw int (5) int是一個(gè)內(nèi)部類型,5是一個(gè)int類型的常數(shù) throw與其操作數(shù) 拋出異常的語句形式:拋出異常的語句形式: throw ; th
8、row通常指定一個(gè)操作數(shù)(或不指定操作數(shù)的特殊情況)通常指定一個(gè)操作數(shù)(或不指定操作數(shù)的特殊情況)。throw的操作數(shù)可以是任何類型,如果操作數(shù)是個(gè)對象,的操作數(shù)可以是任何類型,如果操作數(shù)是個(gè)對象,則稱為異常對象。也可以拋出條件表達(dá)式而不是拋出對象,則稱為異常對象。也可以拋出條件表達(dá)式而不是拋出對象,可以拋出不用于錯(cuò)誤處理的對象??梢話伋霾挥糜阱e(cuò)誤處理的對象。 拋出異常時(shí),生成和初始化拋出異常時(shí),生成和初始化throw操作數(shù)的一個(gè)臨時(shí)副本,操作數(shù)的一個(gè)臨時(shí)副本,然后這個(gè)臨時(shí)對象初始化異常處理器中的參數(shù)。異常處理器然后這個(gè)臨時(shí)對象初始化異常處理器中的參數(shù)。異常處理器執(zhí)行完畢和退出時(shí),刪除臨時(shí)對象
9、執(zhí)行完畢和退出時(shí),刪除臨時(shí)對象。 異常拋出實(shí)例:異常拋出實(shí)例:定義一個(gè)除法函數(shù),當(dāng)除數(shù)為定義一個(gè)除法函數(shù),當(dāng)除數(shù)為0時(shí),拋出一個(gè)用戶時(shí),拋出一個(gè)用戶定義的定義的異常類對象異常類對象,該對象能告訴用戶發(fā)生了除零該對象能告訴用戶發(fā)生了除零錯(cuò)誤。錯(cuò)誤。異常拋出實(shí)例 異常類定義 / Class DivideByZeroException to be used in exception / handling for throwing an exception on a division by zero.class DivideByZeroException private: const char *me
10、ssage; public: DivideByZeroException() : message( attempted to divide by zero ) const char *what() const return message; ;記錄出現(xiàn)的異常情況Message的默認(rèn)值告訴用戶出現(xiàn)了什么異常異常拋出實(shí)例 異常拋出double Div(int x, int y ) if ( y = 0 ) throw DivideByZeroException(); return static_cast ( x ) / y; 這條語句用默認(rèn)構(gòu)造函數(shù)生成了一個(gè)DivedeByZeroExceptio
11、n類的對象,并把這個(gè)對象返回給調(diào)用它的函數(shù),div函數(shù)執(zhí)行結(jié)束異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說明異常捕獲 一個(gè)函數(shù)拋出異常,它必須假定該異常能被捕獲和處理。異常捕獲機(jī)制使得C+可以把問題集中在一處解決。catch捕獲異常 異常處理器放在catch塊中, 形式如下:catch ( ) catch處理器定義自己的范圍。catch在括號中指定要捕獲的對象類型。catch處理器中的參數(shù)可以命名也可以無名。如果是命名參數(shù),則可以在處理器中引用這個(gè)參數(shù)。 如果是無名參數(shù)(只指定匹配拋出對象類型的類型),則信息不從拋出點(diǎn)傳遞到處理器中,只是控制從拋出點(diǎn)轉(zhuǎn)到處
12、理器中許多異常都可以這樣。 catch () 捕獲任意類型的異常。異常捕獲原理 如果一個(gè)異常信號被拋出,異常處理器中第一個(gè)參數(shù)與異常拋出對象相匹配的函數(shù)將捕獲該異常信號,然后進(jìn)入相應(yīng)的catch語句,執(zhí)行異常處理程序。捕獲異常的匹配規(guī)則 匹配條件:下列情況下,catch處理器參數(shù)匹配所拋出對象的類型: 1、 實(shí)際是同一類型。 2、catch處理器參數(shù)類型是所拋出對象類型的public基類。 3、 處理器參數(shù)為基類指針或引用類型,而拋出對象為派生類指針或引用類型。 4、catch處理器為catch(.),捕獲任意類型的異常。 捕獲異常的匹配規(guī)則(續(xù)) 匹配結(jié)果:拋出異常對象類型與catch處理器
13、參數(shù)類型相符時(shí),則兩者相匹配, 程序?qū)?zhí)行該類型的catch塊(即該類型的異常處理器)。 匹配順序:catch中在當(dāng)前活動(dòng)try塊后面第一個(gè)匹配所拋出異常對象的異常處理器將捕獲該異常。按順序搜索異常處理器,尋找匹配項(xiàng),并執(zhí)行第一個(gè)匹配的處理器。處理器執(zhí)行完畢時(shí),控制恢復(fù)到最后一個(gè)catch塊后面的第一條語句。捕獲異常的匹配規(guī)則(續(xù)) 無匹配情況:若某個(gè)拋出對象沒有任何匹配的異常處理器,這時(shí)匹配搜索會(huì)繼續(xù)到外面一層try塊。這個(gè)過程一直繼續(xù),若最終還是沒有任何匹配的異常處理器。這時(shí)調(diào)用terminate(默認(rèn)調(diào)用abort)終止程序。 多匹配情況:若幾個(gè)異常處理器都匹配所拋出的對象,這可能有幾個(gè)
14、原因: 第一,有一個(gè)捕獲任何異常的catch()處理器。 第二,由于繼承層次,派生類對象可以由派生類類型的異常處理器和基類類型的異常處理器捕獲。這時(shí)執(zhí)行第一個(gè)匹配的異常處理器。捕獲異常的匹配規(guī)則(續(xù)) catch(.)總是作為try塊后面的處理器列表中最后一個(gè)處理器。 捕獲基類類型的異常處理器放在捕獲派生類類型的異常處理器之后。 將帶void *參數(shù)類型的異常處理器放在具有其他指針類型的異常處理器后面。除零異常的捕獲int main() int number1, number2; double result; cout number1 number2 ) try result = Div( n
15、umber1, number2 ); cout The quotient is: result endl; catch ( DivideByZeroException ex ) cout Exception occurred: ex.what() n; cout nEnter two integers (end-of-file to end): “; cout endl; return 0;Try語句塊中包含了可能拋出異常的代碼Div,一旦拋出了異常,則退出try語句塊,進(jìn)入try后面的異常捕獲和處理double Div(int x, int y ) if ( y = 0 ) throw Di
16、videByZeroException(); return static_cast ( x ) / y; int main() int number1, number2; double result; cout number1 number2 ) try if (number2=0) throw DivideByZeroException(); result = static_cast( number1)/number2; cout The quotient is: result endl; catch ( DivideByZeroException ex ) cout Exception o
17、ccurred: ex.what() n; cout nEnter two integers (end-of-file to end): ; cout endl; return 0;該程序?qū)嵭辛耸裁垂δ埽?6輸出結(jié)果Enter tow integers (end-of-file to end); l00 7The quotient is: 14.2857Enter tow integers (end-of-file to end); 100 0Exception occurred: attempted to divide by zeroEnter tow integers (end-of-fi
18、le to end); 33 9The quotient is: 3.66667Enter tow integers end-of-file to end): 異常拋出與檢測實(shí)例二int Div(int x, int y) if (y=0) throw y; return x/y;拋出的異常不一定是對象,可以是一個(gè)結(jié)果為內(nèi)置類型的表達(dá)式int main() try cout Div(6,3) endl; cout Div(10,0) endl; cout Div(5,2) endl; catch (int) cout divide by zero endl; cout Its Over end
19、l; return 0;2divide by zeroIts Over調(diào)用一個(gè)函數(shù)時(shí)可能會(huì)收到一個(gè)異常。調(diào)用一個(gè)函數(shù)時(shí)可能會(huì)收到一個(gè)異常。如何知道是否會(huì)收到異常呢?如何知道是否會(huì)收到異常呢?收到的是什么異常?收到的是什么異常?異常規(guī)格聲明異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說明異常規(guī)格說明傳統(tǒng)函數(shù)聲明:返回類型 函數(shù)名(形式參數(shù)表);函數(shù)可以拋出任何異常。通常我們希望在調(diào)用函數(shù)時(shí),知道該函數(shù)會(huì)拋出什么樣的異常。所以允許在函數(shù)原型聲明中指出void f() throw(toobig, toosmall, divzero);函數(shù)會(huì)拋出toobig, to
20、osmall, divzero三種異常void f() throw();函數(shù)不會(huì)有異常拋出。#include class up; class down;void f(int i) throw(up, down);int main() for (int i=1;i=3;+i) try f(i); catch (up) cout up catched endl; catch (down) cout down catched endl; return 0;void f(int i) throw(up,down) switch(i) case 1: throw up(); case 2: throw
21、down(); up catcheddown catched示例#include char *ptr; try /異常模塊 if(ptr=new char64*1024=NULL) throw”Not Enough Memory!”; Catch(char *str) /異常錯(cuò)誤處理模塊/ 錯(cuò)誤處理代碼Cout“Exception:”strendl; 控制通過正常的順序執(zhí)行到try語句,執(zhí)行try塊內(nèi)的保護(hù)段; 如果保護(hù)段內(nèi)沒有異常,則后面的catch子句不被執(zhí)行,程序從異常被拋擲的try塊后的最后一個(gè)catch子句后面的語句繼續(xù)執(zhí)行 如果在保護(hù)段執(zhí)行期間或者在保護(hù)段調(diào)用的任何函數(shù)(直接或者間
22、接的調(diào)用)中有異常被拋擲,則從通過throw運(yùn)算數(shù)創(chuàng)建的對象中創(chuàng)建一個(gè)異常對象(可能包含一個(gè)拷貝構(gòu)造函數(shù)) 如果匹配的處理器沒有找到,則函數(shù)terminate將被自動(dòng)調(diào)用(調(diào)用abort終止程序) 如果找到了一個(gè)匹配的catch程序,且它通過值進(jìn)行捕獲,則其形參通過拷貝異常對象進(jìn)行初始化。#includevoid Excp();Ccass EXpublic EX();EX(); ;Class Demopublic: Demo()cout“creating a Demo object.”endl;Demo()cout“Deleting Demo Object.”endl; ;void Excp()Demo A;coutExcp functi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 勞務(wù)合同和技術(shù)承包
- 個(gè)人勞務(wù)分包合同簡本
- 綠化護(hù)坡施工方案
- 產(chǎn)品測評表-產(chǎn)品用戶反饋收集
- 生物化學(xué)分析實(shí)驗(yàn)技術(shù)練習(xí)題集
- 商場餐飲經(jīng)營商鋪?zhàn)赓U合同
- 農(nóng)民宅基地轉(zhuǎn)讓合同
- 臨汾低溫冷庫施工方案
- 杭州室內(nèi)球場施工方案
- 鋁合金飛廊及蓋板施工方案
- 2025年電力人工智能多模態(tài)大模型創(chuàng)新技術(shù)及應(yīng)用報(bào)告-西安交通大學(xué)
- 學(xué)習(xí)雷鋒主題班會(huì)雷鋒日學(xué)習(xí)雷鋒精神-
- 事故隱患內(nèi)部舉報(bào)獎(jiǎng)勵(lì)制度
- 2020-2024年安徽省初中學(xué)業(yè)水平考試中考?xì)v史試卷(5年真題+答案解析)
- 上春山二部合唱鋼琴伴奏正譜
- 小升初個(gè)人簡歷表
- 電工每日巡查簽到表
- 小學(xué)二年級心理健康教育-打開心門交朋友-(11張PPT)ppt課件
- (完整版)CNC84操作手冊
- PCB鍍金層孔隙率檢驗(yàn)方法研究
- 蹲姿禮儀(課堂PPT)
評論
0/150
提交評論