![C 面向?qū)ο蟪绦蛟O計(第二版)課件 第9章異常處理_第1頁](http://file4.renrendoc.com/view/3edffe51a14eccc547f19dd4bcc8db20/3edffe51a14eccc547f19dd4bcc8db201.gif)
![C 面向?qū)ο蟪绦蛟O計(第二版)課件 第9章異常處理_第2頁](http://file4.renrendoc.com/view/3edffe51a14eccc547f19dd4bcc8db20/3edffe51a14eccc547f19dd4bcc8db202.gif)
![C 面向?qū)ο蟪绦蛟O計(第二版)課件 第9章異常處理_第3頁](http://file4.renrendoc.com/view/3edffe51a14eccc547f19dd4bcc8db20/3edffe51a14eccc547f19dd4bcc8db203.gif)
![C 面向?qū)ο蟪绦蛟O計(第二版)課件 第9章異常處理_第4頁](http://file4.renrendoc.com/view/3edffe51a14eccc547f19dd4bcc8db20/3edffe51a14eccc547f19dd4bcc8db204.gif)
![C 面向?qū)ο蟪绦蛟O計(第二版)課件 第9章異常處理_第5頁](http://file4.renrendoc.com/view/3edffe51a14eccc547f19dd4bcc8db20/3edffe51a14eccc547f19dd4bcc8db205.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
面向?qū)ο蟪绦蛟O計第9章
異常處理主要內(nèi)容●
9.1異常處理概述●
9.2異常處理的實現(xiàn)●
9.3構造函數(shù)、析構函數(shù)與異常處理●
9.4異常匹配●9.5標準異常及層次結構●
9.6異常處理中需要注意的問題學習目標掌握了解標準異常處理及層次結構理解異常處理的基本概念掌握編寫異常處理程序理解掌握異常處理的實現(xiàn)9.1異常處理概述異常就是在程序運行中發(fā)生的難以預料的、不正常的事件而導致偏離正常流程的現(xiàn)象。包括編譯時發(fā)生的錯誤和運行時發(fā)生的錯誤,發(fā)生異常將導致正常流程不能進行,就需要對異常進行處理。異常存在于程序的正常功能之外,并要求程序立即處理。通過異??梢詫栴}的檢測和解決分離,方便了程序的開發(fā)和設計。異常處理(Exceptionhandling)提供了一種標準的方法以處理錯誤,發(fā)現(xiàn)可預知或不可預知的問題,允許開發(fā)者識別、查出和修改錯漏之處。使用異常處理,程序中獨立開發(fā)的各部分能夠就程序執(zhí)行期間出現(xiàn)的問題相互通信,并處理這些問題。異常處理是在運行時刻對異常進行檢測、捕獲、提示、傳遞等過程。它是C++語言的一個重要特征,它提出了出錯處理更加完美的方法。1.異常、異常處理的概念在編譯時,編譯系統(tǒng)能發(fā)現(xiàn)程序中的語法錯誤(如關鍵字拼寫錯,變量名未定義,語句末尾缺分號,括號不配對等),編譯系統(tǒng)會告知用戶在第幾行出錯,是什么樣的錯誤。由于是在編譯階段發(fā)現(xiàn)的錯誤,因此這類錯誤又稱為編譯錯誤。有的初學者寫的并不長的程序,在編譯時會出現(xiàn)十幾個甚至幾十個語法錯誤,使人往往感到手足無措。但是,總的來說,這種錯誤是比較容易發(fā)現(xiàn)和糾正的,因為它們一般都是有規(guī)律的,在有了一定的編譯經(jīng)驗以后,可以很快地發(fā)現(xiàn)出錯的位置和原因并加以改正。(1)語法錯誤1.異常、異常處理的概念
有的程序雖然能通過編譯,也能投入運行,但是在運行過程中會出現(xiàn)異常,得不到正確的運行結果,甚至導致程序不正常終止,或出現(xiàn)死機現(xiàn)象。例如:①訪問數(shù)組元素的下標越界,在越界時又寫入了數(shù)據(jù)或遇到意外的非法輸入;②用new動態(tài)申請內(nèi)存而返回空指針(可能是因內(nèi)存不足);③算術運算上溢出或下溢出;④整數(shù)除法中除數(shù)為0;⑤調(diào)用函數(shù)時提供了無效實參,如指針實參為空指針(如用空指針來調(diào)用strlen函數(shù));⑥通過掛空指針或掛空引用來訪問對象;⑦輸入整數(shù)或浮點數(shù)失??;⑧I/O錯誤。(2)運行錯誤1.異常、異常處理的概念2.
異常處理的基本思想編程正確性總是依賴某些假設成立為前提,異常編程就是要分析識調(diào)用關系異常傳播方向別這些假設不成立的情形,采用面向?qū)ο缶幊碳夹g,建立各種異常類型并形成繼承性架構,以處理程序中可能發(fā)生的各類異常。異常編程的目的是改善程序的可靠性。在大型復雜的程序中,完全不發(fā)生異常幾乎不可能,用傳統(tǒng)的if-else語句來檢查所有可能的異常情形也有很大困難。出錯處理代碼的編寫不再繁瑣錯誤發(fā)生是不會被忽略的圖9-1異常處理模式9.2異常處理的實現(xiàn)9.2異常處理的實現(xiàn)C++提供了對處理異常情況的內(nèi)部支持。C++語言的異常處理語句包括:
引發(fā)異常語句throw和捕獲處理語句try-catch
這兩種語句就是C++語言中用于實現(xiàn)異常處理的機制,有了異常處理程序可以向更高的執(zhí)行上下文傳遞意想不到的事件,從而使程序能更好地從這些事件中恢復過來,異常機制提供程序中錯誤檢測與錯誤處理部分之間的通信。異常處理的語句1.try塊(tryblock)錯誤處理部分用它來處理異常。try語句塊以try關鍵字開始,并以一個或多個catch子句結束。在try塊中執(zhí)行的代碼所拋出(throw)的異常,通常會被其中一個catch子句處理。由于它們“處理”異常,catch子句也稱為處理代碼。
try
{ //語句
}try子句中的語句就是代碼的保護段,這些語句可以是任意C++語句,包括變量聲明,與其它塊語句一樣,try塊引入了局部作用域,塊中聲明的變量不能在外面引用。如果預料程序有可能發(fā)生異常,則將其放在try塊中。9.2異常處理的實現(xiàn)2.
throw表達式(throwexpression)系統(tǒng)通過throw表達式拋出異常,錯誤檢測部分使用這種表達式來說明遇到了無法處理的錯誤。可以說,throw引發(fā)了異常條件。
拋出異常的定義為:
throw表達式由關鍵字throw以及尾隨的表達式組成。其中,表達式的值稱為一個異常,所以執(zhí)行throw語句就稱為拋出異常,可以拋出任意類型的一個值。throw的操作數(shù)在表示異常類型的語法上與return語句的操作數(shù)相似,如果程序中有多處要拋出異常,應該使用不同的操作數(shù)進行區(qū)別,操作數(shù)的值不能用來區(qū)別不同的異常。執(zhí)行throw語句時,try塊就會停止執(zhí)行。如果try塊之后有一個合適的catch塊,控制權就會轉(zhuǎn)交catch塊處理。9.2異常處理的實現(xiàn)【例9-1】處理除零異常的示例/*ch09-1.cpp*/#include<iostream>usingnamespacestd;intDiv(intx,inty);intmain(){try{//除法可能產(chǎn)生除0異常,因此將代碼放入try塊中。 cout<<”5/2=”<<Div(5,2)<<endl; cout<<”8/0=”<<Div(8,0)<<endl; cout<<”7/1=”<<Div(7,1)<<endl; }catch(int){ cout<<”除數(shù)為0”<<endl; } cout<<”that’sok.”<<endl;return0;}intDiv(intx,inty){ if(y==0) throwy;//如果除數(shù)為0,拋出整型異常 returnx/y;}【例9-2】打開指定文件,并將10個整數(shù)寫入文件中。若打開文件失敗,拋出異常。/*ch09-2.cpp*/#include<iostream>#include<fstream>usingnamespacestd;intmain(){ inta[10]={1,2,3,4,5,6,7,8,9,10}; char*filename="d:\\f1.txt"; ofstreamoutfile; outfile.open(filename,ios::out);
try{if(!outfile)throw1;
//拋出異常for(inti=0;i<10;i++) outfile<<a[i]<<""; cout<<endl;}catch(int) //捕獲異常{cout<<"打開文件失敗!"<<endl;} return0;}
異常接口聲明編寫異常處理器必須知道被測試調(diào)用的函數(shù)能拋出哪些類型的異常對象。C++提供了異常接口聲明,即在函數(shù)原型聲明中,位于參數(shù)表列之后,清晰地告訴函數(shù)的使用者:該函數(shù)可能拋出的異常類型,以便使用者能夠方便地捕獲異常對象進行異常處理。帶有異常接口聲明的函數(shù)原型說明的一般形式:返回類型函數(shù)名(參數(shù)表列)throw異常類型名[,…]使用異常規(guī)格說明的函數(shù)原型有三種:(1)拋出指定類型異常對象的函數(shù)原型:voidfunction()throw(toobig,toosmall,divzero);(2)能拋出任何類型異常對象的函數(shù)原型:voidfunction();注意,該形式與傳統(tǒng)的函數(shù)原型聲明形式相同。(3)不拋出任何異常對象的函數(shù)原型:voidfunction()throw()。9.3構造函數(shù)、析構函數(shù)與
異常處理C++異常處理具有處理構造函數(shù)異常的能力。由于構造函數(shù)沒有返回值,如果沒有異常機制,只能按以下兩種選擇報告在構造期間的錯誤:①設置一個非局部的標志并希望用戶檢查它;②希望用戶檢查對象是否被完全創(chuàng)建。這是一個嚴重的問題,因為在C++程序中,對象構造失敗后繼續(xù)執(zhí)行注定是災難。所以構造函數(shù)成為拋出異常最重要的用途之一。使用異常機制是處理構造函數(shù)錯誤的安全有效的方法。然而用戶還必須把注意力集中在對象內(nèi)部的指針上和構造函數(shù)異常拋出時的清除方法上。1.在構造函數(shù)中拋出異常
2.不要在析構函數(shù)中拋出異常由于析構函數(shù)會在拋出異常時被調(diào)用,所以永遠不要在析構函數(shù)中拋出一個異?;蛘咄ㄟ^執(zhí)行在析構函數(shù)中的動作導致其它異常的拋出。否則就意味著在已存在的異常到達引起捕獲之前又拋出一個新的異常,這會導致對terminate()的調(diào)用。換句話講,假若調(diào)用一個析構函數(shù)中的任何函數(shù)都有可能會拋出異常,則這些調(diào)用應該寫在析構函數(shù)中的一個測試塊try中,而且析構函數(shù)必須自己處理所有自身的異常,即這里的異常都不應逃離析構函數(shù)內(nèi)部。【例9-3】測試構造函數(shù)中拋出異常時析構函數(shù)會不會被執(zhí)行。/*ch09-3.cpp*/#include<iostream>#include<string>usingnamespacestd;classMyTest_Base{public:MyTest_Base(stringname=“”):m_name(name){throwstd::exception(“在構造函數(shù)中拋出一個異常,測試!”);cout<<“構造一個MyTest_Base類型對象,對象名為:”<<m_name<<endl;}virtual~MyTest_Base(){cout<<“銷毀一個MyTest_Base類型對象,對象名為:”<<m_name<<endl;}voidFunc()throw(){throwstd::exception(“故意拋出一個異常,測試!”);}voidOther(){}protected:stringm_name;};intmain(){
try{
//對象構造時將會拋出異常
MyTest_Baseobj1(“obj1”);
obj1.Func();
obj1.Other();}catch(std::exceptione){
cout<<e.what()<<endl;}catch(...){
cout<<“unknowexception”<<endl;}return0;}【例9-3】測試構造函數(shù)中拋出異常時析構函數(shù)會不會被執(zhí)行。9.4異常匹配異常是通過拋出對象引發(fā),該對象的類型決定應該激活哪個處理代碼,異常以類似于將實參傳遞給函數(shù)的方式拋出和捕獲。函數(shù)在發(fā)生錯誤時能以拋出異常對象的方式結束函數(shù)執(zhí)行是建立在假定該異常對象能被捕獲和處理的前提下的。這一假定在C++中是成立的,這也是異常處理的一個優(yōu)點。完成函數(shù)調(diào)用時的異常測試,異常對象的捕獲和處理是由try-catch結構實現(xiàn)的,使得處理程序運行錯誤的編碼變得方便、有效,并具有完全的結構化和良好的可讀性。該結構的一般形式如下:try{… //被測試的程序代碼throw…//拋出異常}catch(異常類型異常對象名){… //異常處理的程序代碼}9.4異常匹配1.捕獲某種類型的異常try{… //可能產(chǎn)生異常的代碼}catch(type1id1){… //處理類型為type1的異常}catch(type2id2){… //處理類型為type1的異常}//…每個catch語句相當于一個以特定的異常類型為單一參數(shù)的小型函數(shù),標識符id1、id2等如同函數(shù)中的參數(shù)名,如果對引起該異常對象拋出的程序運行的錯誤處理中無須使用異常對象,則該標識符可省略;異常處理器部分必須緊跟在測試塊try之后;catch語句與switch語句不同,即每個case(情況)引起的執(zhí)行需要加入break實現(xiàn)執(zhí)行的結束;測試塊try中不同函數(shù)的調(diào)用可能會拋出相同的異常對象,而異常處理器中對同一異常對象的處理方法只需要一個。2.捕獲所有類型的異常catch(…){cout<<“anunkownexceptionwasthrown”<<endl;}3.未捕獲的異常如果測試塊try執(zhí)行過程中拋出的異常對象在當前異常處理器沒有被捕獲,則異常對象將進入更高一層的運行環(huán)境中。這種異常對象的拋出、捕獲、處理過程按照運行環(huán)境的調(diào)用關系逐層進行,直到在某個層次的運行環(huán)境的異常處理器中捕獲并恰當處理了異常對象才停止,否則將一直進行至到調(diào)用系統(tǒng)的特定函數(shù)terminate()終止程序運行。例如,在異常對象的創(chuàng)建過程中、異常對象的被處理過程中或異常對象的析構過程中又拋出了新異常對象,就會產(chǎn)生所拋出的異常對象不能被捕獲。【例9-4】捕獲多個異常。/*ch09-4.cpp*/#include<iostream>#include<string>usingnamespacestd;classNegativeNumber{public:NegativeNumber();NegativeNumber(stringcatched);stringget_message();private:stringmessage;};classDivideByZero{};NegativeNumber::NegativeNumber(){}NegativeNumber::NegativeNumber(stringcatched):message(catched){}stringNegativeNumber::get_message(){returnmessage;}intmain(){intchocolatenumber,kidnumber;doublenumber;try{cout<<"請輸入巧克力塊數(shù):\n";cin>>chocolatenumber;if(chocolatenumber<0)throwNegativeNumber("chocolatenumber");cout<<"請輸入小朋友人數(shù):\n";cin>>kidnumber;if(kidnumber<0)throwNegativeNumber("kidnumber");if(kidnumber!=0)number=chocolatenumber/double(kidnumber);elsethrowDivideByZero();cout<<"每個小朋友分得"<<number<<"巧克力。\n";}
catch(NegativeNumbere){cout<<e.get_message()<<"不能為負值。"<<endl;}catch(DivideByZero){cout<<"除數(shù)不能為0.\n";}return0;}【例9-4】捕獲多個異常。9.5標準異常及層次結構
在C++標準庫中提供了一批標準異常類,用于報告在標準庫中的函數(shù)遇到的問題,為用戶在編程中直接使用和作為派生異常類的基類。下表9-1描述了這些標準異常類。9.5標準異常及層次結構類名說明頭文件exception是所有標準異常類的基類。可以調(diào)用它的成員函數(shù)what()獲取其特征的顯示說明。exceptionlogic_errorexception的派生類,報告程序邏輯錯誤,這些錯誤在程序執(zhí)行前可以被檢測到。stdexceptruntime_errorexception的派生類,報告程序運行錯誤,這些錯誤僅在程序運行時可以被檢測到。stdexceptios_base::failureException的派生類,報告I/O操作錯誤,ios_base::clear()可能拋出該異常類對象。iosbase表9-1標準異常類圖9.1標準異常層次結構9.5標準異常及層次結構9.6異常處理中需要注意的問題
使用任何一個新特性必然有所開銷。異常被拋出需要開銷相當?shù)倪\行時間,這就是不要把異常處理用于程序流控制的一部分原因
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 湘教版數(shù)學七年級上冊2.5《整式的加法和減法》聽評課記錄1
- 人教版九年級數(shù)學下冊:28.2.2 《應用舉例》聽評課記錄3
- 生態(tài)供應鏈管理合同(2篇)
- 環(huán)境檢測設備銷售代理合同(2篇)
- 人教版九年級數(shù)學下冊:26.1.1《反比例函數(shù)》 聽評課記錄1
- 魯教版(五四制)地理六年級上冊《學習與探究 學用交通地圖》聽課評課記錄1
- 湘教版地理七年級上冊1.2《我們怎樣學地理》聽課評課記錄
- 人教部編版道德與法治七年級下冊:6.2 《集體生活成就我》 聽課評課記錄4
- 2022年新課標八年級上冊道德與法治第一單元 走進社會生活 聽課評課記錄(1、2課共4課時)
- 蘇科版數(shù)學八年級下冊《菱形》聽評課記錄
- 商業(yè)銀行的風險審計與內(nèi)部控制
- 2024項目管理人員安全培訓考試題及參考答案AB卷
- 2025年與商場合作協(xié)議樣本(5篇)
- 網(wǎng)絡與社交媒體管理制度
- 2025年新能源汽車銷售傭金返點合同范本6篇
- 2025-2030年中國配電變壓器市場未來發(fā)展趨勢及前景調(diào)研分析報告
- GB/T 45120-2024道路車輛48 V供電電壓電氣要求及試驗
- 2025年上海市嘉定區(qū)中考英語一模試卷
- 潤滑油、潤滑脂培訓課件
- 2025年中核財務有限責任公司招聘筆試參考題庫含答案解析
- 寒假綜合實踐活動作業(yè)展示
評論
0/150
提交評論