




已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
C/C+程序設(shè)計教程,鄭秋生 主編,2019/7/11,2,第5章 異常處理及命名空間,本章學(xué)習(xí)重點掌握內(nèi)容: 異常的概念、異常的產(chǎn)生 異常的處理機(jī)制 throw、try和catch的用法 命名空間的概念及使用,2019/7/11,3,第5章 異常處理及命名空間,5.1 異常處理 5.2 命名空間,5.1 異常處理,5.1.1 異常的概念 程序需要在各種不同環(huán)境下使用時,需要考慮在這些異常情況下程序的響應(yīng)能力。 所謂異常(Exception)是程序運行過程中,由于環(huán)境變化、用戶操作失誤以及其它方面的原因而產(chǎn)生的運行時不正常的情況,它要求程序立即進(jìn)行處理,否則將會引起程序錯誤甚至崩潰的現(xiàn)象。,2019/7/11,4,5.1 異常處理,5.1.2 異常處理機(jī)制 C+采用機(jī)制是,當(dāng)本函數(shù)運行出現(xiàn)異常時,可以不在本函數(shù)處理,而是發(fā)出異常信息(拋出異常);調(diào)用者可以捕捉到這一個信息(捕獲異常),根據(jù)對應(yīng)的出錯信息進(jìn)行相應(yīng)的處理(處理異常);或向更上一層調(diào)用發(fā)出異常信息(再次拋出異常)。 C+引入了3個關(guān)鍵字try(檢查異常),throw(拋出異常)和catch(捕獲異常),用于進(jìn)行異常處理。首先,程序員將一組有可能引起異常的語句放在try塊中,當(dāng)程序執(zhí)行過程中,如果遇到錯誤,它就通過throw語句拋出一個異常。而catch塊用來捕捉異常,并進(jìn)行相應(yīng)的處理。,2019/7/11,5,【例5.1】拋出異常到處理異常的過程,#include using namespace std; double divide(double x1, double x2) /輸入偶數(shù),否則產(chǎn)生異常 if(x2=0) throw “除數(shù)為0,無法計算!“; /拋出異常 return x1/x2; / 程序其它部分 ,2019/7/11,6,int main() double x1,x2,dRet ; bool bRet = true; coutx1x2; try dRet = divide(x1,x2); /divide可能拋出異常 catch (char* message) /捕獲異常 bRet =false; coutmessageendl; if(bRet) coutx1“/”x2“=”dRetendl; return 0; ,異常的處理語法,throw 表達(dá)式; 說明:throw后的表達(dá)式表示拋出異常的類型,可以是一個變量、常量或一個對象。throw語句在語法上與return語句相似。 try-catch結(jié)構(gòu)描述如下: try 被檢查語句 catch(異常類型聲明) 異常處理語句 ,2019/7/11,7,異常語法說明-1,1. try塊可以包含任何C+語句,甚至可以包含整個函數(shù),但是try塊必須包含能夠拋出異常的語句。當(dāng)被檢測的函數(shù)出現(xiàn)異常時,catch塊中獲得異常的信息。 2. try 塊和catch塊作為一個整體出現(xiàn),且catch必須緊跟在try塊之后,中間不能插入其他語句。 3. try塊可以單獨出現(xiàn),而無catch塊,表示無論是否有異常都不進(jìn)行處理。 4.一個try-catch結(jié)構(gòu)中,只能有一個try塊,可以有多個catch塊,每個catch塊的異常信息必須是不同的數(shù)據(jù)類型,以使和不同異常信息匹配。,2019/7/11,8,異常語法說明-2,6. try-catch結(jié)構(gòu)可以和throw出現(xiàn)在同一函數(shù)中,這時throw拋出異常后,catch首先和匹配本函數(shù)的拋出的異常,如果匹配則由本函數(shù)catch捕獲否則,由上一層函數(shù)處理。 7. throw可以不包含參數(shù),用于catch捕獲后再原樣拋出,由上一層處理。 8. 異常信息假如沒有被捕捉則異常會發(fā)生。如上述例題例5.1,沒有捕獲異常則0作為除數(shù)相除,引起系統(tǒng)崩潰。 9. 在異常處理過程中也可能存在“單個catch子句不能完全處理這個異?!钡那闆r。那么該異常處理器在做完局部能夠做的事情后,會再一次拋出這個異常,讓更一層函數(shù)處理,也就是重新拋出。,2019/7/11,9,異常語法說明-3,11. throw 拋出的可以是一個常量,也可以是一個變量。關(guān)鍵字throw 還可以靈活地放到很多地方,只要try塊中的語句能直接或間接地執(zhí)行到它。 12. 如果catch中處理程序執(zhí)行完畢,而無返回或終止指令,將跳過后面的catch塊繼續(xù)執(zhí)行程序。 13. catch在比較類型匹配時并不需要完全相同。被throw拋出的異常的數(shù)據(jù)類型與catch 處理程序的參數(shù)類型進(jìn)行匹配的過程, 由精確匹配和自動數(shù)據(jù)類型轉(zhuǎn)換的匹配組成。,2019/7/11,10,兩者類型匹配說明,catch的參數(shù)類型與拋出異常嚴(yán)格匹配; catch的參數(shù)類型是被拋出異常所在類的公有基類; catch的參數(shù)類型是指向基類的指針,2019/7/11,11,【例5.2】重新拋出捕捉異常的例題。,#include using namespace std; void fun2( int x) throw x; void func3(int a) try fun2(a); catch (int x) /這里有x值為a; /如果異常參數(shù)x=0則進(jìn)行處理,否則繼續(xù)拋出 if(x=0) cout“fun3中處理異常!“endl; else cout“重新拋出異常!“endl; throw x; /重新拋出 ,2019/7/11,12,int main() try func3(1); catch (int x) cout“處理了int類型的異常!“endl; return 0; ,【例5.3】類型匹配捕捉異常例題,#include using namespace std; void fun2( int x) throw “拋出異常“; void fun3(int a) try fun2(a); catch (int x) /這里有x值為a; /如果異常參數(shù)x=0則進(jìn)行處理,否則繼續(xù)拋出 cout“fun3檢測到拋出異常!“endl; ,2019/7/11,13,int main() try fun3 (-1); catch (char* str) cout“主函數(shù)捕捉了異常,異常信息是:”strendl; return 0; ,誰捕捉了異常?,程序運行結(jié)果為: 主函數(shù)捕捉了異常,異常信息是:拋出異常,5. 1.3 異常函數(shù),C+引入了異常規(guī)范(Exception Specification)。來時拋出異常函數(shù)的使用者知道拋出異常的類型 異常規(guī)范規(guī)定:隨著函數(shù)聲明列出該函數(shù)可能拋出的異常,并保證該函數(shù)不會拋出其它類型的異常。 C+異常規(guī)范并非強制規(guī)定,因此,沒有在函數(shù)說明后附帶異常說明并非語法錯誤。 目前有些編譯器并不完全支持異常規(guī)范,,2019/7/11,14,常見附帶異常說明函數(shù)說明有以下3種情況。 (1)函數(shù)返回類型 函數(shù)名(參數(shù)列表) throw(類型列表); (2)函數(shù)返回類型 函數(shù)名(參數(shù)列表) throw(); (3)函數(shù)返回類型 函數(shù)名(參數(shù)列表); 說明 在第一種情況中,函數(shù)所有可能拋出的異常類型都列在類型列表中,其中類型列表可以是一到多種數(shù)據(jù)類型,包括自定義數(shù)據(jù)類型。 第二種情況表示函數(shù)不會拋出任何類型的異常。 第三種情況就是函數(shù)的聲明,它表示函數(shù)有可能拋出任何類型的異常。,2019/7/11,15,5. 1.4 標(biāo)準(zhǔn)C+庫中的異常類,在標(biāo)準(zhǔn)C+庫中提供了一個異常類的基類exception和它的多個派生類。用于報告C+標(biāo)準(zhǔn)庫中的函數(shù)在執(zhí)行期間遇到的不正常情況。這些類分別定義在C+標(biāo)準(zhǔn)庫的四個頭文件中, (1)頭文件中定義了異常類exception和bad_exception,異常類exception是標(biāo)準(zhǔn)C+庫中所有異常類的基類。 (2)頭文件中定義了異常類ios_base:failure。 (3)頭文件中定義了異常類bad_cast和bad_typeid,當(dāng)dynamic_cast失敗時將拋出該異常類對象。 (4)頭文件中定義了其它所有的異常類,如logic_error 、out_of_range 、range_error、runtime_error等。,2019/7/11,16,標(biāo)準(zhǔn)C+庫中提供的異常類構(gòu)成了一個類繼承的層次結(jié)構(gòu)。除了報告標(biāo)準(zhǔn)庫中的函數(shù)在執(zhí)行期間遇到的不正常情況外,程序員也可以直接使用這些類編寫程序,或使用這些類作為基類派生自己的異常類。 根類exception定義在頭文件中,是C+標(biāo)準(zhǔn)庫函數(shù)拋出的所有異常的基類。,2019/7/11,17,【例5.5】 異常綜合使用實例,#include #include using namespace std; class CMyException /異常類,該類的對象作為拋出異常時傳遞的異常參數(shù)。 public: CMyException (string n=“none“) : name(n) /構(gòu)造函數(shù),根據(jù)參數(shù)n構(gòu)造一個名字為n的異常類對象 cout“構(gòu)造一個CMyException對象,名稱為:“nameendl; CMyException (const CMyException,2019/7/11,18,class CTestClass /測試類,其構(gòu)造函數(shù)可能拋出int型或char*型異常 public: CTestClass(int x) throw(int); void print(); private: int a; ; CTestClass: CTestClass(int x) throw(int) /本層直接處理char*類型異常,int類型異常由上層處理 try if(x=0) throw 0; if(x1000) throw “x值太大!“; a = x; catch(char* s)/ cout“處理了char*類型異常信息:“sendl; void CTestClass:print() coutaendl; ,異常綜合使用實例-2,void fun1(int x) throw(CMyException, int) / 可能拋出CMyException, int類型異常,但是如果只寫throw(CMyException),編譯器也能編譯通過 CTestClass a(x); a.print(); CMyException obj2(“obj2“); throw obj2; int main() try /拋出指針異常,需要在捕捉中刪除指針, /這種情況本層函數(shù)拋出并捕捉是可以, /如果本層函數(shù)拋出,而調(diào)用者捕捉刪除指針,就不是一個高質(zhì)量的程序 throw new CMyException(“obj1“); catch(CMyException *e) coutGetName()endl; delete e; ,2019/7/11,19,try coutx; fun1(x); catch(int x) cout“處理了int類型的異常:“xendl; catch(char *s)/這個捕捉永遠(yuǎn)不會被處理 cout“處理了char*類型的異常:“sendl; catch(CMyException ,討論,運行結(jié)果發(fā)現(xiàn),fun1中拋出異常后,由產(chǎn)生一個拷貝對象,這是由于拋出對象后,產(chǎn)生了一個臨時對象,捕捉對象采用引用方式,實際上是臨時對象的引用,如果捕捉時,采用值方式,則會再增加一次拷貝。 為減少拷貝的次數(shù),捕捉對象采用引用的方式。,2019/7/11,20,5.2 命名空間,需要程序員使用第三方提供的庫時,必須保證程序中的變量不和第三方提供的庫中的全局實體名字沖突,為了解決這個問題,C+引入命名空間機(jī)制。 5.2.1 命名空間的定義 定義命名空間的語法格式如下。 namespace 命名空間名 聲明序列 ,2019/7/11,21,注意下面幾個方面,namespace只能在全局范疇定義,但它們之間可以互相嵌套,即在命名空間定義內(nèi)容定義一個新的命名空間。 可以通過多次聲明和定義同一命名空間,把新的成員名稱加入到已有的命名空間之中去,即使多次聲明在不同的頭文件中,也是同屬于同一個命名空間體。 一個namespace的名字可以用另一個名字做它的別名。 可以在命名空間之外定義命名空間的成員(如函數(shù)的定義),這時成員的名字必須被命名空間限定修飾。而且如果在命名空間之外定義,則必須則命名空間之內(nèi)聲明。,2019/7/11,22,5.2.2 命名空間的使用,命名空間中成員的引用,需要使用命名空間的域操作符: 如果想直接使用命名空間中的某一成員,而不用命名空間的域操作符??梢圆捎胾sing聲明,using格式如下: using 命名空間:命名空間.:成員名稱,2019/7/11,23,using聲明需要注意下幾點: using聲明的作用域就是using所處位置的作用域,即:如全局域中是從using使用開始到文件結(jié)束,局部域內(nèi)使用則其作用域是局部的。和普通變量一樣,局部變量將隱藏全局變量。 using聲明名字必須在該域內(nèi)是唯一,不能重復(fù)聲明. using 聲明用于直接指定命名空間成員,也可以使用using指定整個命名空間,語法格式為: using namespace 命名空間名:命名空間名;,2019/7/11,24,例子,using namespace std; #include #include using namespace std; namespace myNameSpace1 /自定義命名空間myNameSpace1 string myStr1 = “myStr1“; /在myNameSpace1中嵌套定義命名空間myNameSpace2 namespace myNameS
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣告策劃面試題及答案
- 2024商業(yè)美術(shù)設(shè)計師考試秘笈試題及答案
- 2024年紡織材料改性技術(shù)試題及答案
- 2024年廣告設(shè)計師文化傳播試題及答案
- 平臺測評面試題及答案
- 電工技能操作試題及答案
- 數(shù)字轉(zhuǎn)型對廣告?zhèn)鞑サ纳钸h(yuǎn)影響分析試題及答案
- 大學(xué)數(shù)學(xué)試題題庫及答案
- 2014四川試題及答案
- 安全保護(hù)法試題及答案
- 2022年四川綿竹高發(fā)投資有限公司招聘筆試題庫及答案解析
- 電廠煙囪外壁防腐工程項目施工方案
- 籃球比賽計分表word版
- 上古卷軸5所有任務(wù)代碼
- 2000年40個部門投入產(chǎn)出表
- 《教師職業(yè)道德》全書word版
- 唯美復(fù)古風(fēng)人間煙火氣相冊宣傳模板課件
- 高空作業(yè)安全會議記錄內(nèi)容
- 合同制消防員績效考核細(xì)則詳解
- 00510秘書實務(wù)-自考整合版
- 門禁一卡通系統(tǒng)解決方案
評論
0/150
提交評論