




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第7章 異常處理 寫函數(shù)庫(kù)的程序員可以檢測(cè)到庫(kù)函數(shù)運(yùn)行時(shí)的錯(cuò)誤(如數(shù)寫函數(shù)庫(kù)的程序員可以檢測(cè)到庫(kù)函數(shù)運(yùn)行時(shí)的錯(cuò)誤(如數(shù)組訪問(wèn)越界),但通常卻不知道應(yīng)該如何處理這些錯(cuò)誤組訪問(wèn)越界),但通常卻不知道應(yīng)該如何處理這些錯(cuò)誤 異常處理的基本想法是,讓一個(gè)函數(shù)在發(fā)現(xiàn)了自己無(wú)法處異常處理的基本想法是,讓一個(gè)函數(shù)在發(fā)現(xiàn)了自己無(wú)法處理的錯(cuò)誤時(shí)拋出一個(gè)異常,希望它的(直接或間接)調(diào)用理的錯(cuò)誤時(shí)拋出一個(gè)異常,希望它的(直接或間接)調(diào)用者能夠處理這個(gè)問(wèn)題。者能夠處理這個(gè)問(wèn)題。異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說(shuō)明程序邏輯經(jīng)常對(duì)決定程序下一步怎樣執(zhí)行的條件進(jìn)行測(cè)試程序邏輯經(jīng)
2、常對(duì)決定程序下一步怎樣執(zhí)行的條件進(jìn)行測(cè)試執(zhí)行一個(gè)任務(wù)如果這個(gè)任務(wù)沒(méi)有正確執(zhí)行 則執(zhí)行錯(cuò)誤處理執(zhí)行下一個(gè)任務(wù)如果該任務(wù)沒(méi)有正確執(zhí)行 則執(zhí)行錯(cuò)誤處理傳統(tǒng)錯(cuò)誤處理方法 可以處理的錯(cuò)誤在發(fā)生錯(cuò)誤的地方就地處理可以處理的錯(cuò)誤在發(fā)生錯(cuò)誤的地方就地處理 在檢查到一個(gè)在局部無(wú)法處理的問(wèn)題時(shí),一個(gè)函數(shù)可以:在檢查到一個(gè)在局部無(wú)法處理的問(wèn)題時(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)場(chǎng)進(jìn)行當(dāng)場(chǎng)進(jìn)行錯(cuò)誤處理。在寫錯(cuò)誤處理。在寫程序時(shí),必須知道所有的錯(cuò)誤該如何處理程序時(shí),必須知道所有的錯(cuò)誤該如何處理 好處好處: 程序員閱讀代碼時(shí)能夠程序員閱讀代碼時(shí)能夠直接直接看到錯(cuò)誤處理情況,確看到錯(cuò)誤處理情況,確定是否實(shí)現(xiàn)了正確的錯(cuò)誤檢查。定是否實(shí)現(xiàn)了正確的錯(cuò)誤檢查。 問(wèn)題問(wèn)題: 代碼中受到錯(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)) 這些工具能夠檢測(cè)出錯(cuò)誤,但往往不知道該如何處理這些工具能夠檢測(cè)出錯(cuò)誤,但往往不知道該如何處理錯(cuò)誤。錯(cuò)誤的處理是由工具的使用者決定錯(cuò)誤。錯(cuò)誤的處理是由工具的使用者決定 需要一種機(jī)制能將檢測(cè)到的錯(cuò)誤告訴使用者需要一種機(jī)制能將檢測(cè)到的錯(cuò)誤告訴使用者異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異
5、常 異常規(guī)格說(shuō)明8異常處理的基本思想函數(shù)f()捕獲并處理異常函數(shù)h() 引發(fā)異常函數(shù)g()調(diào)用者異常傳播方向調(diào)用關(guān)系異常處理 C+的新異常處理特性:的新異常處理特性: 異常處理將異常處理將檢測(cè)發(fā)現(xiàn)檢測(cè)發(fā)現(xiàn)錯(cuò)誤的代碼與錯(cuò)誤的代碼與處理處理錯(cuò)誤的代碼分錯(cuò)誤的代碼分開(kāi)來(lái)。程序員的工作也可做相應(yīng)分工(例如,庫(kù)函數(shù)開(kāi)來(lái)。程序員的工作也可做相應(yīng)分工(例如,庫(kù)函數(shù)程序員負(fù)責(zé)檢測(cè)異常,而調(diào)用庫(kù)函數(shù)的另一程序員則程序員負(fù)責(zé)檢測(cè)異常,而調(diào)用庫(kù)函數(shù)的另一程序員則負(fù)責(zé)捕獲與處理異常)。負(fù)責(zé)捕獲與處理異常)。 使程序員可以刪除程序執(zhí)行使程序員可以刪除程序執(zhí)行“主線條主線條”中的錯(cuò)誤處理中的錯(cuò)誤處理代碼,從而提高程序的可
6、讀性和可維護(hù)性。代碼,從而提高程序的可讀性和可維護(hù)性。異常處理基礎(chǔ)簡(jiǎn)介 如果某段程序可能會(huì)拋出異常,則必須通知系統(tǒng)啟動(dòng)如果某段程序可能會(huì)拋出異常,則必須通知系統(tǒng)啟動(dòng)異常處理機(jī)制。即通過(guò)異常處理機(jī)制。即通過(guò)try語(yǔ)句塊實(shí)現(xiàn)。語(yǔ)句塊實(shí)現(xiàn)。 異常處理代碼的一般形式:異常處理代碼的一般形式:try可能拋出異常的代碼 catch(類型1 參數(shù)1) 處理該異常的代碼 catch(類型2 參數(shù)2) 處理該異常的代碼 Try語(yǔ)句塊中包含了可能拋出異常的代碼,一旦拋出了異常,則退出try語(yǔ)句塊,進(jìn)入try后面的異常捕獲和處理異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說(shuō)明拋出
7、異常 如果程序發(fā)生異常情況,而在當(dāng)前的環(huán)境中獲取不到異常處理如果程序發(fā)生異常情況,而在當(dāng)前的環(huán)境中獲取不到異常處理的足夠信息,我們可以的足夠信息,我們可以創(chuàng)建一包含出錯(cuò)信息的對(duì)象并將該對(duì)象并將該對(duì)象拋出當(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ù) 拋出異常的語(yǔ)句形式:拋出異常的語(yǔ)句形式: throw ; th
8、row通常指定一個(gè)操作數(shù)(或不指定操作數(shù)的特殊情況)通常指定一個(gè)操作數(shù)(或不指定操作數(shù)的特殊情況)。throw的操作數(shù)可以是任何類型,如果操作數(shù)是個(gè)對(duì)象,的操作數(shù)可以是任何類型,如果操作數(shù)是個(gè)對(duì)象,則稱為異常對(duì)象。也可以拋出條件表達(dá)式而不是拋出對(duì)象,則稱為異常對(duì)象。也可以拋出條件表達(dá)式而不是拋出對(duì)象,可以拋出不用于錯(cuò)誤處理的對(duì)象??梢話伋霾挥糜阱e(cuò)誤處理的對(duì)象。 拋出異常時(shí),生成和初始化拋出異常時(shí),生成和初始化throw操作數(shù)的一個(gè)臨時(shí)副本,操作數(shù)的一個(gè)臨時(shí)副本,然后這個(gè)臨時(shí)對(duì)象初始化異常處理器中的參數(shù)。異常處理器然后這個(gè)臨時(shí)對(duì)象初始化異常處理器中的參數(shù)。異常處理器執(zhí)行完畢和退出時(shí),刪除臨時(shí)對(duì)象
9、執(zhí)行完畢和退出時(shí),刪除臨時(shí)對(duì)象。 異常拋出實(shí)例:異常拋出實(shí)例:定義一個(gè)除法函數(shù),當(dāng)除數(shù)為定義一個(gè)除法函數(shù),當(dāng)除數(shù)為0時(shí),拋出一個(gè)用戶時(shí),拋出一個(gè)用戶定義的定義的異常類對(duì)象異常類對(duì)象,該對(duì)象能告訴用戶發(fā)生了除零該對(duì)象能告訴用戶發(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; 這條語(yǔ)句用默認(rèn)構(gòu)造函數(shù)生成了一個(gè)DivedeByZeroExceptio
11、n類的對(duì)象,并把這個(gè)對(duì)象返回給調(diào)用它的函數(shù),div函數(shù)執(zhí)行結(jié)束異常處理 傳統(tǒng)錯(cuò)誤處理方法 異常處理機(jī)制 拋出異常 捕獲異常 處理異常 異常規(guī)格說(shuō)明異常捕獲 一個(gè)函數(shù)拋出異常,它必須假定該異常能被捕獲和處理。異常捕獲機(jī)制使得C+可以把問(wèn)題集中在一處解決。catch捕獲異常 異常處理器放在catch塊中, 形式如下:catch ( ) catch處理器定義自己的范圍。catch在括號(hào)中指定要捕獲的對(duì)象類型。catch處理器中的參數(shù)可以命名也可以無(wú)名。如果是命名參數(shù),則可以在處理器中引用這個(gè)參數(shù)。 如果是無(wú)名參數(shù)(只指定匹配拋出對(duì)象類型的類型),則信息不從拋出點(diǎn)傳遞到處理器中,只是控制從拋出點(diǎn)轉(zhuǎn)到處
12、理器中許多異常都可以這樣。 catch () 捕獲任意類型的異常。異常捕獲原理 如果一個(gè)異常信號(hào)被拋出,異常處理器中第一個(gè)參數(shù)與異常拋出對(duì)象相匹配的函數(shù)將捕獲該異常信號(hào),然后進(jìn)入相應(yīng)的catch語(yǔ)句,執(zhí)行異常處理程序。捕獲異常的匹配規(guī)則 匹配條件:下列情況下,catch處理器參數(shù)匹配所拋出對(duì)象的類型: 1、 實(shí)際是同一類型。 2、catch處理器參數(shù)類型是所拋出對(duì)象類型的public基類。 3、 處理器參數(shù)為基類指針或引用類型,而拋出對(duì)象為派生類指針或引用類型。 4、catch處理器為catch(.),捕獲任意類型的異常。 捕獲異常的匹配規(guī)則(續(xù)) 匹配結(jié)果:拋出異常對(duì)象類型與catch處理器
13、參數(shù)類型相符時(shí),則兩者相匹配, 程序?qū)?zhí)行該類型的catch塊(即該類型的異常處理器)。 匹配順序:catch中在當(dāng)前活動(dòng)try塊后面第一個(gè)匹配所拋出異常對(duì)象的異常處理器將捕獲該異常。按順序搜索異常處理器,尋找匹配項(xiàng),并執(zhí)行第一個(gè)匹配的處理器。處理器執(zhí)行完畢時(shí),控制恢復(fù)到最后一個(gè)catch塊后面的第一條語(yǔ)句。捕獲異常的匹配規(guī)則(續(xù)) 無(wú)匹配情況:若某個(gè)拋出對(duì)象沒(méi)有任何匹配的異常處理器,這時(shí)匹配搜索會(huì)繼續(xù)到外面一層try塊。這個(gè)過(guò)程一直繼續(xù),若最終還是沒(méi)有任何匹配的異常處理器。這時(shí)調(diào)用terminate(默認(rèn)調(diào)用abort)終止程序。 多匹配情況:若幾個(gè)異常處理器都匹配所拋出的對(duì)象,這可能有幾個(gè)
14、原因: 第一,有一個(gè)捕獲任何異常的catch()處理器。 第二,由于繼承層次,派生類對(duì)象可以由派生類類型的異常處理器和基類類型的異常處理器捕獲。這時(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語(yǔ)句塊中包含了可能拋出異常的代碼Div,一旦拋出了異常,則退出try語(yǔ)句塊,進(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): 異常拋出與檢測(cè)實(shí)例二int Div(int x, int y) if (y=0) throw y; return x/y;拋出的異常不一定是對(duì)象,可以是一個(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ī)格說(shuō)明異常規(guī)格說(shuō)明傳統(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; 控制通過(guò)正常的順序執(zhí)行到try語(yǔ)句,執(zhí)行try塊內(nèi)的保護(hù)段; 如果保護(hù)段內(nèi)沒(méi)有異常,則后面的catch子句不被執(zhí)行,程序從異常被拋擲的try塊后的最后一個(gè)catch子句后面的語(yǔ)句繼續(xù)執(zhí)行 如果在保護(hù)段執(zhí)行期間或者在保護(hù)段調(diào)用的任何函數(shù)(直接或者間
22、接的調(diào)用)中有異常被拋擲,則從通過(guò)throw運(yùn)算數(shù)創(chuàng)建的對(duì)象中創(chuàng)建一個(gè)異常對(duì)象(可能包含一個(gè)拷貝構(gòu)造函數(shù)) 如果匹配的處理器沒(méi)有找到,則函數(shù)terminate將被自動(dòng)調(diào)用(調(diào)用abort終止程序) 如果找到了一個(gè)匹配的catch程序,且它通過(guò)值進(jìn)行捕獲,則其形參通過(guò)拷貝異常對(duì)象進(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 function throw an exception!endl;throw EX();void main()TrycoutNow call Excp function.endl;Excp();catch(EX a )cout An Ex exception occurred.endl;catch(.)cou
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 文具安全教案課件
- 印刷業(yè)互聯(lián)網(wǎng)+與融合發(fā)展考核試卷
- 冷藏車運(yùn)輸企業(yè)風(fēng)險(xiǎn)管理與內(nèi)部控制系統(tǒng)考核試卷
- 天然氣藏動(dòng)態(tài)模擬與預(yù)測(cè)考核試卷
- 影視錄放設(shè)備顯示技術(shù)考核試卷
- 文化藝術(shù)與城市品牌建設(shè)考核試卷
- 木片干燥技術(shù)與木材應(yīng)力釋放考核試卷
- 健身器材行業(yè)企業(yè)文化建設(shè)與品牌形象提升考核試卷
- 保險(xiǎn)業(yè)與新能源保險(xiǎn)市場(chǎng)的機(jī)遇與挑戰(zhàn)應(yīng)對(duì)策略案例分析考核試卷
- 制糖業(yè)的可持續(xù)發(fā)展評(píng)估考核試卷
- 勞務(wù)合同協(xié)議書(shū)書(shū)
- 白城2025年吉林大安市事業(yè)單位面向上半年應(yīng)征入伍高校畢業(yè)生招聘5人筆試歷年參考題庫(kù)附帶答案詳解
- 全球人工智能產(chǎn)業(yè)發(fā)展現(xiàn)狀和趨勢(shì)
- 2025年內(nèi)蒙古化工職業(yè)學(xué)院高職單招職業(yè)技能測(cè)試近5年??及鎱⒖碱}庫(kù)含答案解析
- 民法典解讀之婚姻家庭編
- 2025年菏澤醫(yī)學(xué)??茖W(xué)校高職單招數(shù)學(xué)歷年(2016-2024)頻考點(diǎn)試題含答案解析
- 2025年漯河職業(yè)技術(shù)學(xué)院高職單招職業(yè)技能測(cè)試近5年??及鎱⒖碱}庫(kù)含答案解析
- Unit 2 What time is it?-A Let's spell(課件)-2024-2025學(xué)年人教PEP版英語(yǔ)四年級(jí)下冊(cè)
- 2024-2025學(xué)年人教版數(shù)學(xué)六年級(jí)下冊(cè)第二單元百分?jǐn)?shù)(二)(含答案)
- 創(chuàng)新教案:《歌唱二小放牛郎》在2025年音樂(lè)教學(xué)中的應(yīng)用
- 2024年西安電力高等專科學(xué)校高職單招職業(yè)技能測(cè)驗(yàn)歷年參考題庫(kù)(頻考版)含答案解析
評(píng)論
0/150
提交評(píng)論