《异常处理1.ppt》由会员分享,可在线阅读,更多相关《异常处理1.ppt(44页珍藏版)》请在三一办公上搜索。
1、2023/8/3,異常處理(1),1,異常處理,2023/8/3,異常處理(1),2,異常處理(execption handling),異常處理能夠讓使用者有機會修改錯誤,並讓程式繼續執行!異常處理是一種機制,允許兩個各自獨立開發的程式組件能夠在程式執行期間發生不正常情況時彼此通訊.不正常情況亦即所謂的異常,exception.以下是異常處理大概的流程:程式遇到不正常情況 throw exception.處理異常狀況的程式去 catch exception.,2023/8/3,異常處理(1),3,異常處理流程範例,try catch(發生 例外)專門處理 程式catch(發生 例外)專門處理
2、程式繼續下面的程式!,處理完畢,2023/8/3,異常處理(1),4,丟出一個異常throwing an exception,所謂Exception是一種在程式執行期間可偵測到的不正常情況,例如:除以0存取陣列邊界以外元素過度使用記憶體.程式遇到異常,就是丟出(throw)一個exception.語法:throw object;,2023/8/3,異常處理(1),5,攔截除0的例外,#include using namespace std;void main()int d=0;try int data=500/d;catch()cout“發生例外”endl;,Try Block,馬上來看看最簡
3、單的例子,class Error/定義錯誤物件 public:int no;/紀錄錯誤型態;int main(int argc,char*argv)try throw Error();/丟出錯誤物件catch(Error,Try Block,再看看指標的例子丟出error物件,class Error public:int no;/紀錄錯誤型態;int main(int argc,char*argv)try throw new Error();/丟出錯誤catch(Error*obj)int errorno=obj-no;/catch 住 Error型態錯誤 delete obj;return
4、0;,注意:這次有new,2023/8/3,異常處理(1),8,較完整的例子,Simple Exception Demo,2023/8/3,異常處理(1),9,丟出多種錯誤物件範例,void iStack:pop(int,main()try StackObject-pop(top);catch(popOnEmpty)catch(Error1)catch(Error2),丟出popOnEmpty的物件,抓住popOnEmpty型態例外,2023/8/3,異常處理(1),10,丟出錯誤陣列的範例,/stackExcp.h/陣列操作錯誤紀錄物件class ArrayError/*/;/例外處理obj
5、ect,void Matrix:setData(int y,int x,int data)if(y 最大Row|y 最大Col|x 0)throw pArrayError(“超出存取範圍”);/出錯,/丟出例外 Bufferyx=data;,2023/8/3,異常處理(1),11,丟出錯誤 Stack Example,void iStack:pop(int/出錯,丟出例外,/stackExcp.h/定義一個 專門處理Stack例外的classclass popOnEmpty/*/;/例外處理object,2023/8/3,異常處理(1),12,Stack範例-1,範例程式:StackNoExc
6、eptionDemoC語言異常處理程式設計的缺點異常處理和正常程序混雜在一起了.對於大程式會增加維護及技術轉移的困難.,2023/8/3,異常處理(1),13,Stack範例-2,利用例外處理堆疊:*StackWithExceptionDemo異常處理和正常stack處理分開來.使程式碼較容易維護及閱讀.不必再測試每個function傳回值是否成功,2023/8/3,異常處理(1),14,void iStack:pop(int,int main()try StackObject-pop(top);catch(popOnEmpty)catch(Error2)cout,程式結束,try block
7、控制流程,2023/8/3,異常處理(1),15,try block控制流程,如果沒有任何exception發生時=try block中的程式碼會被執行完畢=相關的catch子句將不會執行.如果在try block 之中有exception發生=執行權會跳離 try block,=進入符合的catch子句中.如果沒有符合的catch子句,則執行權會跳到C+Standard library所定義的terminate()函式去.,沒有任何exception發生時,try/正常程式 int data=0;IO-DoIO();/執行 IO 沒有發生異常 data+;,catch(相對應異常類型)異常處
8、理程式,跳過異常處理的部分,有exception發生,try/正常程式 int data=0;IO-DoIO();/執行 IO 發生異常 data+;,catch(相對應異常類型)異常處理程式,執行異常處理程式,你有可能發生的錯誤 1,2023/8/3,異常處理(1),19,try block的Local Scope性質,一個try block 會帶來一個 local scope.宣告於try block中的變數無法被外界看見.就算是相對應catch子句也看不見.,int main()try iStack StackObject;/宣告StackObjectStackObject-pop(to
9、p);catch(popOnEmpty)int I=StackObject-Size;/error 不能使用/StackObject,StacoObject 已被刪除了,2023/8/3,異常處理(1),20,catch子句,Catch為專門用來抓住exception.當try block內的某個敘述句丟出一個exception,=後面相對應的catch子句便會被挑選出來.catch子句由三部份構成:如果某個catch子句中選,其符合述句便被執行.,catch(char*)or catch(char*errString),關鍵字,例外型別或物件,處理statment,2023/8/3,異常處理
10、(1),21,堆疊輾轉開解(Stack Unwinding),func3throw“error”;,func2 func3();,func1 try func2();catch(char*),都找不到對應的catch子句,則呼叫C+standard library中的terminate();,範例程式:CatchDemo.cpp,2023/8/3,異常處理(1),22,exception declaration-1,兩種 catch子句:.1.catch(char*)/只有型別宣告2.catch(char*mes)/object宣告 例外相關資訊由object傳回來使用object宣告的時機:
11、catch子句要讀取例外物件相關資訊.,2023/8/3,異常處理(1),23,exception declaration-2,兩種抓取例外傳值方式catch(Exception e)/call by valuecatch(Exception&e)/call by reference Call by reference的好處可以避免大型 class object所造成的不必要的拷貝動作.亦可修改 Exception 物件,2023/8/3,異常處理(1),24,Call by reference 範例,trythrow Error1();catch(Error1,完整範例:CallByRef.
12、dsw,2023/8/3,異常處理(1),25,exception object的特性,例外物件:由 throw 算式時建立的.當 throw 全域變數:Step 1:先建立exception objectStep 2:再把全域變數的值拷貝到exception object.注意:最後 catch 到的物件是全域變數的複製品看看後面的範例,你有可能發生的錯誤 2,throw 全域例外物件的例子,Error1 obj;/建立全區域例外物件實體,初值為123int main(int argc,char*argv)tryfun();catch(Error1,完整範例:ThrowGlobe.dsw,1
13、23(因為全區域變數是用 copy),丟出全區域物件 obj,1,2,3,整理一下:throw 區域例外物件,int main(int argc,char*argv)tryfun();catch(Error1/丟出錯誤物件,你也可以這樣寫:throw Error1();,2023/8/3,異常處理(1),29,重新丟出(rethrow)-1,使用時機:單獨一個catch子句有可能無法完全處理某個異常情況,在進行了對異常狀況的某些修補動作之後,catch子句可能會決定將exception送往更上層的呼叫端函式(calling function)去處理.語法:throw;,2023/8/3,異常處
14、理(1),30,重新丟出(rethrow)-2,這個動作只能出現在catch子句敘述句中,例如:catch(exception eObj)if(canHandle(eObj)return;/處理完了就returnelse throw;/否則就交由更高層處理,2023/8/3,異常處理(1),31,重新丟出(rethrow)-3,在一連串的catch中,如果要修改並記錄exception object內容,則需要將catch子句的exception declaration宣告為reference,例如:catch(int範例程式:RethowDemo.cpp,更有效率的方法,2023/8/3,異
15、常處理(1),32,Catch-All 1(抓住所有的例外),catch子句的exception declaration 如果是“”代表可以接受任何型別的exception,例如:catch()/任何exception都會被抓到因為一旦match到相對映的catch,就不再檢驗了,故catch()子句最好放在最後一個.範例程式:CatchAllDemo.cpp,2023/8/3,異常處理(1),33,Catch-All-2,特殊用途:利用 exception 來處理 release 資源的應用用於配置系統資源,想要在帶著一個exception退離之前先釋放這些資源.void manip()re
16、source res;res.lock();/鎖定資源try/運用res,可能有exeption catch()res.release();throw;res.relase();/如果發生沒有處理 的例外,則此行就執行不到.,所以把所有的例外可能都抓住.,2023/8/3,異常處理(1),34,異常規格,如何知道你使用的function會丟出那些exception?在使用exception 時,我們必須知道那些function會丟出exception,並且丟出的例外種類?異常規格(Exception Specifications):就是用來解決這樣的問題.範例程式:ESDemo.cpp,202
17、3/8/3,異常處理(1),35,異常規格,函式的宣告:(宣告某個函數會丟出那些exception)函式的定義:,class iStack public:/void pop(int,void pop(int&value)throw(popOnEmpty)/pop函式會 throw popOnEmpty例外,2023/8/3,異常處理(1),36,異常規格,void pop(int/該function可能丟出任何一種的例外,2023/8/3,異常處理(1),37,異常規格,當某個 function 違反了規則時,怎麼辦?Run-time時,若沒有相對映的catch,則會呼叫standard fu
18、nction=unexpected()因為exception是run-time才發生的,所以只有在run-time才會發現,所以,compiling 不會有任何錯誤出現看一下例子Exception Specification.doc,井民全修改 debut.cis.nctu.edu.tw/ching,End,2023/8/3,異常處理(1),39,練習題-型別轉換工具函式,請撰寫一系列的工具函式,這些函式包括下列功能(一個函式包含一個功能):int to string,string to intfloat to string,string to floatint to hex string並利
19、用 throwcatch 做異常處理.其中string代表C+Standard Library的string class.,2023/8/3,異常處理(1),40,練習題提示-1,轉換可以利用 sprintf()和 sscanf(),他們被定義在 stdio.h中.(可能比較方便)sprintf(char*buf,char*format,參數列);根據參數列資料依照format格式輸出字串到buf中.sscanf(char*buf,char*format,參數列);從buf中讀取符合format中的資料,存到參數列所描述的變數記憶體位置的記憶體.,2023/8/3,異常處理(1),41,練習題
20、提示-2,使用範例:char buf100;float fv,sf;cinfv;sprintf(buf,”%f”,fv);sscanf(buf,”%f”,2023/8/3,異常處理(1),42,練習題提示-3,%dint%ffloat%schar*%cchar%ldlong%x十六進位數字,(a,b,c,d,e,f)%X十六進位數字,(A,B,C,D,E,F),2023/8/3,異常處理(1),43,練習題提示-4,string class必須#include並且在下一行加上 using namespace std;簡單的使用範例:string str(“ABC”);/宣告變數並給初值str.c_str();/輸出 char*型別的字串str1;/第二個字元.,2023/8/3,異常處理(1),44,練習題提示-5,異常處理大概可以針對下列情況發出exception:錯誤的字串,例如“123.34af”轉成 float.,