面向?qū)ο蟪绦蛟O(shè)計(jì)異常處理_第1頁
已閱讀1頁,還剩27頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、《面向?qū)ο蟪绦蛟O(shè)計(jì)》,八、異常處理,內(nèi)容提要,程序中潛在的異常問題異常處理機(jī)制C++中的異常處理標(biāo)準(zhǔn)異常使用異常處理應(yīng)注意的幾個(gè)問題,提出問題,【例】求解一元二次方程ax2+bx+c=0#include#includeusing namespace std;int main(){float a,b,c;double x1,x2;cout>a>>b>>c;x1=(-b+sqr

2、t(b*b-4*a*c))/2*a;x2=(-b-sqrt(b*b-4*a*c))/2*a;cout<<"方程的實(shí)根是: x1="<<x1<<" x2="<<x2<<endl;return 0;},程序中潛在的異常問題,問題的分析能夠正常運(yùn)行的程序可能存在很多潛在隱患。程序運(yùn)行時(shí)可以檢測到的一些非正常情況稱為異常(Exce

3、ption)。如除數(shù)為0,數(shù)組越界訪問,內(nèi)存空間不夠,輸入輸出不正常(文件找不到、輸入數(shù)據(jù)類型錯(cuò)等)等等。異常是程序錯(cuò)誤一種形式。程序中的錯(cuò)誤按性質(zhì)可分為:語法錯(cuò)誤(關(guān)鍵字拼寫錯(cuò)、標(biāo)識(shí)符未定義、語句不完整等)邏輯錯(cuò)誤(算法設(shè)計(jì)有誤導(dǎo)致得不到期望結(jié)果)異常(出現(xiàn)是不可避免的,必須加以控制和處理),異常處理機(jī)制,需要進(jìn)行異常處理,從而減少異常對(duì)程序運(yùn)行的影響,提高程序的容錯(cuò)性。異常處理機(jī)制提供了系統(tǒng)層次上的標(biāo)準(zhǔn)設(shè)施,其主要任務(wù)有

4、以下幾點(diǎn):能夠在異常發(fā)生時(shí),在執(zhí)出點(diǎn)拋出異常,并將有關(guān)異常的信息以類型的形式傳遞到異常處理模塊;建立模塊之間的異常通信機(jī)制,特別是在多層模塊之間實(shí)現(xiàn)異常有序的傳遞,保證拋出的每個(gè)異常都能被適當(dāng)?shù)漠惓L幚砟K捕獲。保證異常發(fā)生時(shí)能自動(dòng)釋放異常模塊所占用的系統(tǒng)資源。對(duì)于不執(zhí)行異常處理的代碼沒有任何額外的運(yùn)行負(fù)擔(dān)。將異常處理代碼從普通代碼中分離出來。,C++中的異常處理,異常的拋出、檢測和捕獲異常在多層模塊間的傳遞異常接口聲明

5、異常處理中析構(gòu)函數(shù)的調(diào)用異常類的層次結(jié)構(gòu),異常的拋出、檢測和捕獲,異常拋出、檢測和捕獲的語法定義如下:異常拋出:throw 表達(dá)式;異常的檢測和捕獲由try-catch結(jié)構(gòu)實(shí)現(xiàn):try{被檢測可能會(huì)發(fā)生異常的語句}catch(異常的類型){異常處理的語句},int main() {float a,b,c;double x1,x2;cout>a>>b>>c;try {if

6、(0 == a) throw a;// b并無意義,代表float型即可if((b*b-4*a*c)<0) throw 1.0;x1=(-b+sqrt(b*b-4*a*c))/2*b;x2=(-b-sqrt(b*b-4*a*c))/2*b;cout<<"方程的實(shí)根是: x1="<<x1<<" x2="<<x2<&

7、lt;endl;}catch(float)//捕獲float類型的異常{ cout<<"系數(shù)b不能為0,方程無解!"<<endl; }catch(double)//捕獲double類型的異常{ cout<<"開方為負(fù)值,方程無解!"<<endl; }cout<<"程序結(jié)束!"<

8、;<endl;return 0;},異常在多層模塊間的傳遞,【例】函數(shù)嵌套情況下的異常處理typedef struct zero//聲明除數(shù)為零異常類型{string s;}ZERO;typedef struct negative//聲明開方值為負(fù)異常類型{string s;}NEGATIVE;fun2(int a,int b,int c)//拋出異常的函數(shù){ZERO s1;NEGATIVE s

9、2; s1.s="除數(shù)為零";s2.s="開方值為負(fù)數(shù)";if(0 == a) throw s1;if((b*b-4*a*c)<0) throw s2;return sqrt(b*b-4*a*c);},fun1(int a,int b,int c) { //捕獲異常并重新拋出異常try{ return (-b+fun2(a,b,c))/(2*a); }

10、catch(ZERO){ throw;//重新拋出異常 }}int main() {float a,b,c;cout>a>>b>>c;try{ cout<<"方程的一個(gè)實(shí)根是: x1="<<fun1(a,b,c)<<endl; }catch(ZERO S1) //捕獲除數(shù)為零異常,并處理異常{ cout<&l

11、t;S1.s<<",方程無解!"<<endl; }catch(NEGATIVE S2)// 捕獲開方值為負(fù)數(shù)異常,并處理異常{ cout<<S2.s<<",方程無解!"<<endl; }cout<<"程序結(jié)束!"<<endl;return 0;},異常接口聲明,在使用可能拋出異

12、常的函數(shù)時(shí),可能需要知道該函數(shù)拋出的異常類型,C++專門提供了異常接口聲明,也稱為異常規(guī)范。其語法形式如下:函數(shù)類型 函數(shù)名(函數(shù)參數(shù)表) throw (異常類型表)其中異常類型表包括該函數(shù)中所有可以拋出的異常類型,異常類型之間用逗號(hào)分開。異常接口聲明是函數(shù)接口的一部分,是函數(shù)使用者和函數(shù)之間的協(xié)議。,異常處理中析構(gòu)函數(shù)的調(diào)用,#include using namespace std;void Fun( void );cl

13、ass intArray { public:intArray(int n) {p = new int[ n ]; cout<<"構(gòu)造intArray,分配具有”<<n<<“個(gè)元素的數(shù)組。" << endl;}~intArray() {delete[] p;cout << "析構(gòu)intArr

14、ay,釋放資源。" << endl;}private:int *p;};,void Fun() {intArray ia(10);cout<< "在Fun()中拋擲整型異常。" << endl; throw 1;}int main() {try {cout << "在主函數(shù)的try塊中調(diào)用函數(shù)Fun()。&quo

15、t;<< endl;Fun();}catch( int ) {cout << "在主函數(shù)catch子句捕獲到整型異常," ;cout << "并進(jìn)行異常處理。"<< endl;}cout << "程序結(jié)束!" << endl;return 0;},異常類的層次結(jié)構(gòu),#

16、include #include using namespace std;class Excp { //聲明異?;?public:static void print( string msg )// 打印錯(cuò)誤信息{ cout<<msg<<endl; }};class pushOnFull : public Excp { //聲明棧滿異常類public:pushOnFull( int i

17、) : tempvalue( i ) { }int getTempValue() { return tempvalue; }private:int tempvalue; //存放異常發(fā)生時(shí)沒有壓棧的值};,class popOnEmpty : public Excp { };//聲明??债惓n?class newError : public Excp { }; //聲明動(dòng)態(tài)分配內(nèi)存異常類 class otherError

18、 : public Excp { };//聲明其它異常類 class Stack {public:Stack( int capacity=10 ) throw (newError);//建立一空棧~Stack(){delete[] elements;};//析構(gòu)函數(shù),釋放數(shù)組資源void push( int value ) throw (pushOnFull);//壓棧void pop(int &top_va

19、lue) throw (popOnEmpty);//出棧bool isfull(){return top < maxsize? false : true;};bool isempty(){return top ? false : true;};int size(){ return top; }void display();private:int top;//棧頂指針int * elements;//存放棧

20、中元素的棧數(shù)組int maxsize;//??扇菁{元素的個(gè)數(shù)};,Stack::Stack( int capacity):top(0), maxsize(capacity) {elements = new int[capacity]; //動(dòng)態(tài)創(chuàng)建棧數(shù)組if(0==elements) throw newError();//如果分配失敗拋出異常}void Stack::pop( int &top_value

21、 ) {if ( isempty() ) throw popOnEmpty();//棧空,則拋出異常top_value = elements[ --top ];}void Stack::push( int value ) {if ( isfull() )throw pushOnFull(value);//棧滿拋出異常elements[top++ ] = value;}void Stack::display

22、() {if ( !size() ){ cout << "棧中已沒有元素!\n"; return; }cout << "(棧中有 " << size() << "個(gè)元素)( bottom: ";for ( int i = 0; i < top; ++i )cout << elements[

23、i] << " ";cout << " :top )\n";},int main() {int i,n,count;try {cout >n;Stack myStack(n);cout >n;for ( i = 1; i >n;for ( i = 1; i <= n; count=i++ ){ in

24、t x;myStack.pop( x );}cout << "已出棧"<<count<<"個(gè)元素!\n";},catch(pushOnFull e) {e.print("棧已滿!");cout << "棧中有"<<count-1<<"個(gè)元素,

25、";cout<<"值為"<<e.getTempValue()<<"的元素沒有壓入棧\n";}catch(newError){ newError::print("給棧分配空間時(shí)出錯(cuò)!"); }catch(popOnEmpty) { cout << "已出棧"<<

26、count<<"個(gè)元素,";popOnEmpty::print("棧已空!");}catch(Excp){ Excp::print("程序其它異常在此處理!"); }return 0;},標(biāo)準(zhǔn)異常,C++標(biāo)準(zhǔn)庫提供的標(biāo)準(zhǔn)異常類的層次結(jié)構(gòu),標(biāo)準(zhǔn)異常,標(biāo)準(zhǔn)異常的根是exception類 ,其聲明如下:namespace std { //exc

27、eption 類在命名空間std 中class exception {public:exception() throw();//缺省構(gòu)造函數(shù)exception( const exception & ) throw();//拷貝構(gòu)造函數(shù)exception& operator=( const exception& ) throw(); virtual ~exception() throw();//析

28、構(gòu)函數(shù)// what()返回一個(gè)字符串,用于異常的文本描述。 virtual const char* what() const throw();};},標(biāo)準(zhǔn)異常的使用#include//標(biāo)準(zhǔn)異常的頭文件#include#includeusing namespace std;class Array {public:Array(const char *source, int sz) { size = sz

29、; ca = new char[size]; for ( int i = 0; i < size; ++i )if ( !source ) ca[i] = 0;else ca[i] = source[i];},char &operator[]( int i ) const { if ( i = size ) {string es =

30、"數(shù)組越界!";throw out_of_range( es ); //將es字符串傳入對(duì)象 } return ca[i];}private:int size;char *ca;};,int main() {try { char ca[] = { 'A','B','C','D','E',

31、'F'}; Array CA( ca, sizeof(ca)/sizeof(char) ); CA[5]='X';//正常訪問字符數(shù)組類 CA[6]='G';//越界訪問數(shù)組類將引發(fā)異常 return 0;}catch ( const out_of_range &excp ) { cout<< excp.what()<

32、;<endl;//獲取異常信息 return -1;}},使用異常處理應(yīng)注意的幾個(gè)問題,在C++的程序設(shè)計(jì)中,異常處理應(yīng)主要用于獨(dú)立開發(fā)的程序模塊之間的異常通信。異常處理機(jī)制的使用會(huì)影響程序的執(zhí)行效率。因此,即使C++支持異常處理,在程序設(shè)計(jì)時(shí)也應(yīng)該具體情況具體分析。在設(shè)計(jì)一個(gè)模塊時(shí),如果該模塊發(fā)生異常時(shí)遇到下列情況,則考慮使用異常處理機(jī)制:該模塊本身不知道如何處理發(fā)生的異常,而將由其上級(jí)模塊負(fù)責(zé)對(duì)異常的判斷,并

33、選擇采取適當(dāng)?shù)男袆?dòng)。該模塊必須自己處理異常理問題,或者如果它不能完全處理則必須把異常情況“告訴”給使用該模塊的上級(jí)模塊,由其上級(jí)模塊進(jìn)行處理。,使用異常處理應(yīng)注意的幾個(gè)問題,使用標(biāo)準(zhǔn)異常和異常接口聲明在創(chuàng)建自定義的異常類型前,應(yīng)檢查標(biāo)準(zhǔn)C++異常庫。如果標(biāo)準(zhǔn)異常正合所需,就拿來為我所用,這樣會(huì)使我們的程序更易于理解和使用。如果標(biāo)準(zhǔn)異常不能滿足要求,則盡量從某個(gè)標(biāo)準(zhǔn)異常中派生新增加的異常類型。異常接口聲明像一個(gè)函數(shù)原型:它完整列舉了

34、函數(shù)可能拋出的所有異常。異常接口聲明是函數(shù)及其調(diào)用者間契約的一部分。換句話說,函數(shù)承諾不拋出其它任何不在異常接口聲明中的異常。在函數(shù)設(shè)計(jì)時(shí)聲明異常接口,即便于用戶了解函數(shù)的異常類型,又能給編譯器提供該函數(shù)的拋出異常的種類,讓編譯器“監(jiān)督”函數(shù)是否按照其聲明拋出異常。,使用異常處理應(yīng)注意的幾個(gè)問題,不要將異常處理當(dāng)成程序控制結(jié)構(gòu)來使用異常的拋出和捕獲有點(diǎn)像函數(shù)的調(diào)用與返回,而try-catch結(jié)構(gòu)看上去像switch語句。如果在程序中把

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論