C++大學基礎教程第十三章_第1頁
C++大學基礎教程第十三章_第2頁
C++大學基礎教程第十三章_第3頁
C++大學基礎教程第十三章_第4頁
C++大學基礎教程第十三章_第5頁
已閱讀5頁,還剩50頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、2022-4-141C+大學基礎教程大學基礎教程第第1313章章 異常處理異常處理北京郵電大學電信工程學院北京郵電大學電信工程學院 計算機技術中心計算機技術中心程序設計的要求之一就是程序的健壯性。希望程序在運行時能夠不出或者少出問題。但是,在程序的實際運行時,總會有一些因素會導致程序不能正常運行。異常處理(Exception Handling)就是要提出或者是研究一種機制,能夠較好的處理程序不能正常運行的問題。 第十三章第十三章 異常處理異常處理13.1 13.1 異常和異常處理異常和異常處理 13.2 C+13.2 C+異常處理機制異常處理機制 13.3 13.3 用類的對象傳遞異常用類的對

2、象傳遞異常 13.4 13.4 異常處理中的退棧和對象析構異常處理中的退棧和對象析構 13.1 13.1 異常和異常處理異常和異常處理2022-4-14北京郵電大學電信工程學院計算機技術中心-5-13.1.1 異常及其特點異常及其特點 異常(異常(ExceptionsExceptions)是程序在運行時可能出現是程序在運行時可能出現的會導致程序運行終止的錯誤。的會導致程序運行終止的錯誤。 編譯系統檢查出來的語法錯誤,導致程序運行編譯系統檢查出來的語法錯誤,導致程序運行結果不正確的邏輯錯誤,都不屬于異常的范圍。結果不正確的邏輯錯誤,都不屬于異常的范圍。 異常是一個可以正確運行的程序在運行中可能異

3、常是一個可以正確運行的程序在運行中可能發生的錯誤。發生的錯誤。 2022-4-14北京郵電大學電信工程學院計算機技術中心-6-13.1.1 異常及其特點異常及其特點常見的異常,如:常見的異常,如: n系統資源不足。如內存不足,不可以動態申系統資源不足。如內存不足,不可以動態申請內存空間;磁盤空間不足,不能打開新的請內存空間;磁盤空間不足,不能打開新的輸出文件,等。輸出文件,等。 n用戶操作錯誤導致運算關系不正確。如出現用戶操作錯誤導致運算關系不正確。如出現分母為分母為0 0,數學運算溢出,數組越界,參數,數學運算溢出,數組越界,參數類型不能轉換,等。類型不能轉換,等。 2022-4-14北京郵

4、電大學電信工程學院計算機技術中心-7-13.1.1 異常及其特點異常及其特點異常有以下的一些特點:異常有以下的一些特點: n偶然性。程序運行中,異常并不總是會發生偶然性。程序運行中,異常并不總是會發生的。的。 n可預見性。異常的存在和出現是可以預見的。可預見性。異常的存在和出現是可以預見的。 n嚴重性。一旦異常發生,程序可能終止,或嚴重性。一旦異常發生,程序可能終止,或者運行的結果不可預知。者運行的結果不可預知。 2022-4-14北京郵電大學電信工程學院計算機技術中心-8-13.1.2 異常處理方法及舉例異常處理方法及舉例對于程序中的異常,通常有三種處理的對于程序中的異常,通常有三種處理的方

5、法:方法: n不作處理。很多程序實際上就是不處理異常不作處理。很多程序實際上就是不處理異常的。的。 n發布相應的錯誤信息,然后,終止程序的運發布相應的錯誤信息,然后,終止程序的運行。在行。在C C語言的程序中,往往就是這樣處理語言的程序中,往往就是這樣處理的。的。 n適當的處理異常,一般應該使程序可以繼續適當的處理異常,一般應該使程序可以繼續運行。運行。 2022-4-14北京郵電大學電信工程學院計算機技術中心-9-13.1.2 異常處理方法及舉例異常處理方法及舉例一般來說,異常處理(一般來說,異常處理(Exception HandlingException Handling)就是在程序運行時

6、對異常進行檢測和控制。就是在程序運行時對異常進行檢測和控制。而在而在C+C+中,異常處理(中,異常處理(EHEH)就是用就是用C+C+提供的提供的trytrythrowthrowcatchcatch的模式進行異常處理的機的模式進行異常處理的機制。制。 2022-4-14北京郵電大學電信工程學院計算機技術中心-10- 例例13.1 13.1 程序將連續地輸入兩個實數,通過調用函數,返回這程序將連續地輸入兩個實數,通過調用函數,返回這兩個數相除的商。并且要注意除數不能為兩個數相除的商。并且要注意除數不能為0 0。 / /例例13.1 13.1 用一般的方法處理除法溢出用一般的方法處理除法溢出# #

7、include include #include #include double divide(double a, double b)double divide(double a, double b) if (b = 0)if (b = 0)/ /檢測分母是不是為檢測分母是不是為0 0 coutcout 除數不可以等于除數不可以等于0 !0 !endlendl; ;abort();abort();/ /調用調用abortabort函數終止運行函數終止運行 return a/b;return a/b; 2022-4-14北京郵電大學電信工程學院計算機技術中心-11- void main()voi

8、d main()double x,y,z;double x,y,z; coutcout x y) x y) z = divide(x,y);z = divide(x,y);coutcout x x 除以除以 y y 等于等于 z n;z n;coutcout 輸入下一組數輸入下一組數 : ;: ; coutcout Bye!n; Bye!n; 2022-4-14北京郵電大學電信工程學院計算機技術中心-12- 如果出現分母為如果出現分母為0 0 的情況,運行將出現以下結果:的情況,運行將出現以下結果:2022-4-14北京郵電大學電信工程學院計算機技術中心-13-13.1.2 異常處理方法及舉例

9、異常處理方法及舉例這個程序中,對于除數為這個程序中,對于除數為0 0的處理有這樣的處理有這樣的特點:的特點: n異常的檢測和處理都是在一個程序模塊異常的檢測和處理都是在一個程序模塊(dividedivide函數)中進行的;函數)中進行的; n由于函數的返回值是由于函數的返回值是doubledouble型的數據,因此,型的數據,因此,即使檢測到除數為即使檢測到除數為0 0的情況,也不能通過返的情況,也不能通過返回值來反映這個異常。只能調用函數回值來反映這個異常。只能調用函數abortabort終止程序的運行。終止程序的運行。 13.2 C+13.2 C+異常處理機制異常處理機制 2022-4-1

10、4北京郵電大學電信工程學院計算機技術中心-15-13.2 C+C+異常處理機制異常處理機制 C+C+處理異常有兩個基本的做法:處理異常有兩個基本的做法: n異常的檢測和處理是在不同的代碼段中進行的。一異常的檢測和處理是在不同的代碼段中進行的。一般的說法是在般的說法是在“try”try”部分檢測異常,部分檢測異常,“catch”catch”部部分處理異常。分處理異常。 n由于異常的檢測和處理不是在同一個代碼段中進行由于異常的檢測和處理不是在同一個代碼段中進行的,在檢測異常和處理異常的代碼段之間需要有一的,在檢測異常和處理異常的代碼段之間需要有一種傳遞異常信息的機制,在種傳遞異常信息的機制,在C+

11、C+中是通過中是通過“對象對象”來傳遞異常的。這種對象可以是一種簡單的數據來傳遞異常的。這種對象可以是一種簡單的數據(如整數),也可以是系統定義或用戶自定義的類(如整數),也可以是系統定義或用戶自定義的類的對象。的對象。 2022-4-14北京郵電大學電信工程學院計算機技術中心-16-13.2 C+C+異常處理機制異常處理機制 C+C+異常處理的語法可以表述如下:異常處理的語法可以表述如下: trytry 受保護語句受保護語句; ; throw throw 異常異常; ; 其他語句其他語句; ; catch(catch(異常類型異常類型) ) 異常處理語句異常處理語句; ; 檢測和拋擲檢測和拋

12、擲異常異常撲獲和處理撲獲和處理異常異常try模塊模塊2022-4-14北京郵電大學電信工程學院計算機技術中心-17-13.2 C+C+異常處理機制異常處理機制 在在C+C+術語中,異常(術語中,異常(ExceptionException,注意結尾沒注意結尾沒有有s s)是作為專用名詞出現的。就是將異常檢是作為專用名詞出現的。就是將異常檢測程序所拋擲的測程序所拋擲的“帶有異常信息的對象帶有異常信息的對象”稱為稱為“異常異常”。而將捕獲異常的處理程序稱為異常處理程序而將捕獲異常的處理程序稱為異常處理程序(Exception HandlerException Handler)。)。 2022-4-1

13、4北京郵電大學電信工程學院計算機技術中心-18-13.2 C+C+異常處理機制異常處理機制 在在trytry復合語句中,可以調用其他函數,在所復合語句中,可以調用其他函數,在所調用的函數中檢測和拋擲異常,而不是在調用的函數中檢測和拋擲異常,而不是在trytry復合語句中直接拋擲異常。這個所調用的函數,復合語句中直接拋擲異常。這個所調用的函數,仍然是屬于這個仍然是屬于這個trytry模塊的,所以這個模塊中模塊的,所以這個模塊中的的catchcatch部分,仍然可以捕獲它所拋擲的異常部分,仍然可以捕獲它所拋擲的異常并進行處理。并進行處理。 2022-4-14北京郵電大學電信工程學院計算機技術中心-

14、19- 例例13.2 13.2 用用C+C+的異常處理機制,重新處理例的異常處理機制,重新處理例13.113.1。 / /例例13.213.2用用C+C+的異常處理機制,處理除法溢出的異常處理機制,處理除法溢出# #include include #include #include double divide(double a, double b)double divide(double a, double b) if (b = 0)if (b = 0) throw throw 輸入錯誤:除數不可以等于輸入錯誤:除數不可以等于0 !;0 !; return a/b; return a/b; 2

15、022-4-14北京郵電大學電信工程學院計算機技術中心-20- void main()void main()double x,y,z;double x,y,z; coutcout x y) x y) try try z = divide(x,y); z = divide(x,y); catch (const char catch (const char * * s) s)/ start of exception handler/ start of exception handler coutcout s n; s n;coutcout 輸入一對新的實數:輸入一對新的實數: ; ;continu

16、e;continue; / end of handler/ end of handler coutcout x x 除以除以 y y 等于等于 z n;z n; coutcout 輸入下一組數輸入下一組數 : ;: ; coutcout 程序結束,再見程序結束,再見! !n;n; 2022-4-14北京郵電大學電信工程學院計算機技術中心-21-13.2 C+C+異常處理機制異常處理機制程序運行的一種結果是:程序運行的一種結果是:輸入兩個實數輸入兩個實數 x x 和和 y y :1.2 3.21.2 3.2x x 除以除以 y y 等于等于 0.375 0.375輸入下一組數輸入下一組數 : 3

17、.4 0: 3.4 0輸入錯誤:除數不可以等于輸入錯誤:除數不可以等于0 !0 !輸入一對新的實數:輸入一對新的實數: 2.3 4.5 2.3 4.5x x 除以除以 y y 等于等于 0.511111 0.511111輸入下一組數輸入下一組數 : : q q程序結束,再見程序結束,再見! !2022-4-14北京郵電大學電信工程學院計算機技術中心-22-13.2 C+C+異常處理機制異常處理機制閱讀這個程序,可以注意以下幾點:閱讀這個程序,可以注意以下幾點: n在在trytry的復合語句中,調用了函數的復合語句中,調用了函數dividedivide。因此,因此,盡管盡管dividedivid

18、e函數是在函數是在trytry模塊的外面定義的,它仍模塊的外面定義的,它仍然是屬于然是屬于trytry模塊:在模塊:在trytry語句塊中運行;語句塊中運行; ndividedivide函數檢測到異常后,拋擲出一個字符串作為函數檢測到異常后,拋擲出一個字符串作為異常對象,異常的類型就是字符串類型;異常對象,異常的類型就是字符串類型; ncatchcatch程序塊指定的異常對象類型是程序塊指定的異常對象類型是charchar* *,可以捕可以捕獲字符串異常。捕獲異常后的處理方式是通過獲字符串異常。捕獲異常后的處理方式是通過continuecontinue語句,跳過本次循環,也不輸出結果,直語句,

19、跳過本次循環,也不輸出結果,直接進入下一次循環,要求用戶再輸入一對實數。接進入下一次循環,要求用戶再輸入一對實數。2022-4-14北京郵電大學電信工程學院計算機技術中心-23-13.2 C+C+異常處理機制異常處理機制例例13.213.2的執行過程可以簡要的表示如下:的執行過程可以簡要的表示如下: 2022-4-14北京郵電大學電信工程學院計算機技術中心-24-13.2 C+C+異常處理機制異常處理機制另外,在編寫帶有異常處理的程序時,還要注另外,在編寫帶有異常處理的程序時,還要注意:意: ntrytry語句塊和語句塊和catchcatch語句塊是一個整體,語句塊是一個整體,兩者之兩者之間不

20、能有其他的語句間不能有其他的語句; n一個一個trytry語句塊后面可以有多個語句塊后面可以有多個catchcatch語句,但語句,但是,不可以幾個是,不可以幾個trytry語句塊后面用一個語句塊后面用一個catchcatch語語句。句。 13.3 13.3 用類的對象傳遞異常用類的對象傳遞異常 2022-4-14北京郵電大學電信工程學院計算機技術中心-26-13.3 用類的對象傳遞異常用類的對象傳遞異常throwthrow語句所傳遞的異常,可以是各種類型的:語句所傳遞的異常,可以是各種類型的:整型、實型、字符型、指針,等等。也可以用整型、實型、字符型、指針,等等。也可以用類對象來傳遞異常。類

21、對象來傳遞異常。 對象就是既有數據屬性,也有行為屬性。使用對象就是既有數據屬性,也有行為屬性。使用對象來傳遞異常,就是既可以傳遞和異常有關對象來傳遞異常,就是既可以傳遞和異常有關的數據屬性,也可以傳遞和處理異常有關的行的數據屬性,也可以傳遞和處理異常有關的行為或者方法。為或者方法。 專門用來傳遞異常的類稱為異常類。異常類可專門用來傳遞異常的類稱為異常類。異常類可以是用戶自定義的,也可以是系統提供的以是用戶自定義的,也可以是系統提供的exceptionexception類。類。 2022-4-14北京郵電大學電信工程學院計算機技術中心-27-13.3.1用戶自定義類的對象傳遞異常用戶自定義類的對

22、象傳遞異常 我們用第十章中的棧類模板來作為例子,類模我們用第十章中的棧類模板來作為例子,類模板中兩個主要的函數板中兩個主要的函數pushpush和和poppop的定義中,都的定義中,都安排了錯誤檢查的語句,以檢查棧空或者棧滿安排了錯誤檢查的語句,以檢查棧空或者棧滿的錯誤。由于的錯誤。由于poppop函數是有返回值的,在棧空函數是有返回值的,在棧空的條件下,是沒有數據可以出棧的。盡管的條件下,是沒有數據可以出棧的。盡管poppop函數可以檢測到這種錯誤,但是,也不可能正函數可以檢測到這種錯誤,但是,也不可能正常的返回,于是只好通過常的返回,于是只好通過exitexit函數調用結束程函數調用結束程

23、序的執行。序的執行。 2022-4-14北京郵電大學電信工程學院計算機技術中心-28-13.3.1用戶自定義類的對象傳遞異常用戶自定義類的對象傳遞異常現在,我們用現在,我們用C+C+異常處理的機制,改寫這個異常處理的機制,改寫這個程序。要求改寫后的程序不僅有更好的可讀性,程序。要求改寫后的程序不僅有更好的可讀性,而且在棧空不能出棧時,程序也可以繼續運行,而且在棧空不能出棧時,程序也可以繼續運行,使得程序有更好的健壯性。使得程序有更好的健壯性。 可以定義兩個異常類:一個是可以定義兩個異常類:一個是“棧空異常棧空異常”類,類,另一個是另一個是“棧滿異常棧滿異常”類。在類。在trytry塊中,如果塊

24、中,如果檢測到檢測到“棧空異常棧空異常”,就,就throwthrow一個一個“StackEmptyExceptionStackEmptyException”類的對象。如果檢類的對象。如果檢測到測到“棧滿異常棧滿異常”,就,就throwthrow一個一個“StackOverflowExceptionStackOverflowException”類的對象。類的對象。 2022-4-14北京郵電大學電信工程學院計算機技術中心-29-13.3.1用戶自定義類的對象傳遞異常用戶自定義類的對象傳遞異常例例13.3 13.3 通過對象傳遞異常。用通過對象傳遞異常。用C+C+異常處理機異常處理機制來處理棧操作

25、中的制來處理棧操作中的“棧空異常棧空異常”和和“棧滿異棧滿異常常”。定義兩個相應的異常類。通過異常類對。定義兩個相應的異常類。通過異常類對象來傳遞檢測到的異常,并且對異常進行處理。象來傳遞檢測到的異常,并且對異常進行處理。要求在棧空的時候用要求在棧空的時候用poppop函數出棧失敗時,程函數出棧失敗時,程序的運行也不終止。序的運行也不終止。 2022-4-14北京郵電大學電信工程學院計算機技術中心-30- / /例例13.313.3:帶有異常處理的棧:帶有異常處理的棧# #include include using namespace std;using namespace std;class

26、 class StackOverflowExceptionStackOverflowException/ /棧滿異常類棧滿異常類 public: public: StackOverflowExceptionStackOverflowException() () StackOverflowExceptionStackOverflowException() () void void getMessagegetMessage() () coutcout 異常:棧滿不能入棧。異常:棧滿不能入棧。 endlendl; ; ; ;class class StackEmptyExceptionStackEm

27、ptyException/ /棧空異常類棧空異常類 public: public: StackEmptyExceptionStackEmptyException() () StackEmptyExceptionStackEmptyException() () void void getMessagegetMessage() () coutcout 異常:棧空不能出棧。異常:棧空不能出棧。 endlendl; ; ; ;2022-4-14北京郵電大學電信工程學院計算機技術中心-31- template class T, template i / /類模板定義類模板定義class class My

28、StackMyStack T T StackBufferiStackBufferi; ; intint size; size;intint top; top;public:public: MyStackMyStack( void ) : size( i ) top = i;( void ) : size( i ) top = i; void push( const T item ); void push( const T item ); T pop( void ); T pop( void ); ;2022-4-14北京郵電大學電信工程學院計算機技術中心-32- template class

29、T, template i /push/push成員函數定成員函數定義義void void MyStackMyStack:push( const T item ):push( const T item ) if( top 0 ) if( top 0 ) StackBufferStackBuffer-top = item;-top = item; else else throw throw StackOverflowExceptionStackOverflowException();(); / /拋擲對象異常拋擲對象異常 return;return; 2022-4-14北京郵電大學電信工程學院計

30、算機技術中心-33- template class T, template i /pop/pop成員函數定成員函數定義義T T MyStackMyStack:pop( void ):pop( void ) if( top i ) if( top i ) return return StackBuffertopStackBuffertop+;+; else else throw throw StackEmptyExceptionStackEmptyException();();/ /拋擲另一個對象異常拋擲另一個對象異常 2022-4-14北京郵電大學電信工程學院計算機技術中心-34- void

31、main()void main()/ /帶有異常處理的帶有異常處理的類模板測試程序類模板測試程序 MyStackMyStack ssss; ;for(intfor(int i=0;i10;i+) i=0;i10;i+)trytry if(i%3)cout if(i%3)coutss.popss.pop()()endlendl; ; else else ss.push(iss.push(i); ); catch ( catch (StackOverflowExceptionStackOverflowException &e) &e) e.getMessagee.getMessag

32、e(); (); catch ( catch (StackEmptyExceptionStackEmptyException &e) &e) e.getMessagee.getMessage(); (); coutcoutByen;Byen; 程序執行的結果是:程序執行的結果是:0 0異常:棧空不能出棧。異常:棧空不能出棧。3 3異常:棧空不能出棧。異常:棧空不能出棧。6 6異常:棧空不能出棧。異常:棧空不能出棧。ByeBye2022-4-14北京郵電大學電信工程學院計算機技術中心-35-13.3.1用戶自定義類的對象傳遞異常用戶自定義類的對象傳遞異常這個例子和例這個例子和例1

33、3.213.2有一些明顯不同的地方:有一些明顯不同的地方: n通過對象傳遞參數。具體來說,是在通過對象傳遞參數。具體來說,是在throwthrow語句語句中直接調用異常類的構造函數,生成一個無名中直接調用異常類的構造函數,生成一個無名對象(如:對象(如:throw throw StackEmptyExceptionStackEmptyException();();),),來傳遞異常的。來傳遞異常的。 n在在catchcatch語句中規定的異常類型則是異常類對象語句中規定的異常類型則是異常類對象的引用。當然,也可以直接用異常類對象作為的引用。當然,也可以直接用異常類對象作為異常。異常。 2022

34、-4-14北京郵電大學電信工程學院計算機技術中心-36-13.3.1用戶自定義類的對象傳遞異常用戶自定義類的對象傳遞異常n通過異常類對象的引用,直接調用異常類的成員函通過異常類對象的引用,直接調用異常類的成員函數數getMessagegetMessage,來處理異常。來處理異常。 n在在trytry語句塊后面直接有兩個語句塊后面直接有兩個catchcatch語句來捕獲異常。語句來捕獲異常。也就是說,要處理的異常增加時,也就是說,要處理的異常增加時,catchcatch語句的數語句的數目也要增加。目也要增加。 n運行結果表明,運行結果表明,1010次循環都已經完成。沒有出現因次循環都已經完成。沒

35、有出現因為空棧時不能出棧而退出運行的情況。為空棧時不能出棧而退出運行的情況。 2022-4-14北京郵電大學電信工程學院計算機技術中心-37-13.3.2 用用exception類對象傳遞異常類對象傳遞異常C+C+提供了一個專門用于傳遞異常的類:提供了一個專門用于傳遞異常的類:exceptionexception類。類。可以通過可以通過exceptionexception類的對象來傳遞異常。類的對象來傳遞異常。 class exceptionclass exception public: public: exception(); exception();/默認構造函數默認構造函數 except

36、ion(char exception(char * *););/字符串作參數的構造函數字符串作參數的構造函數 exception(const exception&);exception(const exception&); exception& operator= (const exception&); exception& operator= (const exception&); virtual exception(); virtual exception();/虛析構函數虛析構函數 virtual char virtual char * *

37、 what() const; what() const;/what()/what()虛函數虛函數private:private: char char * * m_what; m_what; ; ;2022-4-14北京郵電大學電信工程學院計算機技術中心-38-13.3.2 用用exception類對象傳遞異常類對象傳遞異常其中和傳遞異常最直接有關的函數有兩個:其中和傳遞異常最直接有關的函數有兩個: n帶參數的構造函數。參數是字符串,一般就是帶參數的構造函數。參數是字符串,一般就是檢測到異常后要顯示的異常信息。檢測到異常后要顯示的異常信息。 nwhat()what()函數。返回值就是構造函數。返

38、回值就是構造exceptionexception類對象類對象時所輸入的字符串。可以直接用插入運算符時所輸入的字符串。可以直接用插入運算符“”“”在顯示器上顯示。在顯示器上顯示。 2022-4-14北京郵電大學電信工程學院計算機技術中心-39-13.3.2 用用exception類對象傳遞異常類對象傳遞異常如果捕獲到如果捕獲到exceptionexception類對象后,只要顯示類對象后,只要顯示關于異常的信息,則可以直接使用關于異常的信息,則可以直接使用exceptionexception類。如果除了錯誤信息外,還需類。如果除了錯誤信息外,還需要顯示其他信息,或者作其他的操作,則要顯示其他信息

39、,或者作其他的操作,則可以定義一個可以定義一個exceptionexception類的派生類,在派類的派生類,在派生類中可以定義虛函數生類中可以定義虛函數whatwhat的重載函數,的重載函數,以便增加新的信息的顯示。以便增加新的信息的顯示。 2022-4-14北京郵電大學電信工程學院計算機技術中心-40-13.3.2 用用exception類對象傳遞異常類對象傳遞異常例例13.4 13.4 定義一個簡單的數組類。在數組類定義一個簡單的數組類。在數組類中重載中重載“ ”“ ”運算符,目的是對于數組元運算符,目的是對于數組元素的下標進行檢測。如果發現數組元素下素的下標進行檢測。如果發現數組元素下

40、標越界,就拋擲一個對象來傳遞異常。并標越界,就拋擲一個對象來傳遞異常。并且要求處理異常時可以顯示越界的下標值。且要求處理異常時可以顯示越界的下標值。2022-4-14北京郵電大學電信工程學院計算機技術中心-41-13.3.2 用用exception類對象傳遞異常類對象傳遞異常我們使用我們使用exceptionexception類的對象來傳遞對象。但是,類的對象來傳遞對象。但是,直接使用直接使用exceptionexception類對象還是不能滿足例題的要類對象還是不能滿足例題的要求。因為不能傳遞越界的下標值。求。因為不能傳遞越界的下標值。 為此,可以定義一個為此,可以定義一個exception

41、exception類的派生類類的派生類ArrayOverflowArrayOverflow。其中包含一個數據成員其中包含一個數據成員k k。在構在構造造ArrayOverflowArrayOverflow類對象時,用越界的下標值初始類對象時,用越界的下標值初始化這個數據化這個數據k k。在在catchcatch塊中捕獲到這個對象后,塊中捕獲到這個對象后,可以設法顯示對象的可以設法顯示對象的k k值。值。 2022-4-14北京郵電大學電信工程學院計算機技術中心-42- / /例例13.4 13.4 用用exceptionexception類參與處理異常類參與處理異常# #include inc

42、lude #include #include using namespace std;using namespace std;class class ArrayOverflowArrayOverflow : public exception : public exception/exception/exception類的派生類類的派生類 public: public: ArrayOverflow:ArrayOverflow(intArrayOverflow:ArrayOverflow(int i) i) : exception( : exception( 數組越界異常數組越界異常! !n )

43、k=i; n ) k=i; const char const char * * what() what()/ /重新定義的重新定義的what()what()函數函數 coutcout數組下標數組下標kk=0 & i=0 & iszsz) return pi;) return pi; throw throw ArrayOverflowArrayOverflow( i );( i ); 2022-4-14北京郵電大學電信工程學院計算機技術中心-44- void void f(MyArrayf(MyArray &v); &v);void main()void main

44、() MyArrayMyArray A(10); A(10); f(A); f(A); void f( void f( MyArrayMyArray& v )& v )/ for(intfor(int i=0;i3;i+) i=0;i3;i+) try if(i!=1) vi=i; try if(i!=1) vi=i; coutcoutviviendlendl; ;else vv.size( )+10=10;else vv.size( )+10=10; catch( catch( ArrayOverflowArrayOverflow &r ) &r ) cout

45、coutr.what();r.what(); /for/for循環結束循環結束 程序運行后輸出:程序運行后輸出:0 0數組下標數組下標2020越界越界數組越界異常數組越界異常! !2 213.4 13.4 異常處理中的退棧異常處理中的退棧 和對象析構和對象析構 2022-4-14北京郵電大學電信工程學院計算機技術中心-46-13.4異常處理中的退棧和對象析構異常處理中的退棧和對象析構 在函數調用時,函數中定義的自動變量在函數調用時,函數中定義的自動變量將在堆棧中存放。結束函數調用時,這將在堆棧中存放。結束函數調用時,這些自動變量就會從堆棧中彈出,不再占些自動變量就會從堆棧中彈出,不再占用堆棧的

46、空間,這個過程有時被稱為用堆棧的空間,這個過程有時被稱為“退棧退棧”(Stack unwindingStack unwinding)。)。其他的其他的結束動作還包括調用析構函數,釋放函結束動作還包括調用析構函數,釋放函數中定義的對象。數中定義的對象。 2022-4-14北京郵電大學電信工程學院計算機技術中心-47-13.4異常處理中的退棧和對象析構異常處理中的退棧和對象析構但是,如果函數執行時出現異常,并且但是,如果函數執行時出現異常,并且只是采用簡單的顯示異常信息,然后退只是采用簡單的顯示異常信息,然后退出(出(exitexit)程序的做法,則程序的執行程序的做法,則程序的執行就會突然中斷,

47、結束函數調用時必須完就會突然中斷,結束函數調用時必須完成的退棧和對象釋放的操作也不會進行。成的退棧和對象釋放的操作也不會進行。這樣的結果是很不希望的。這樣的結果是很不希望的。 2022-4-14北京郵電大學電信工程學院計算機技術中心-48- float function3(int k)float function3(int k)/function3/function3中可能有異常中可能有異常 if(k=0)if(k=0) coutcoutfunction3function3中發生異常中發生異常 n;n;/ /顯示異常信息顯示異常信息 exit(1);exit(1);/ /退出執行退出執行 el

48、se return 123/k;else return 123/k; void function2(int n)void function2(int n) ForTestForTest A12; A12; function3(n); function3(n);/ /第三次調用第三次調用 void function1(int m) void function1(int m) ForTestForTest A11; A11; function2(m); function2(m);/ /第二次調用第二次調用 void main()void main() function1(0); function1

49、(0);/ /第一次調用第一次調用 2022-4-14北京郵電大學電信工程學院計算機技術中心-49-13.4異常處理中的退棧和對象析構異常處理中的退棧和對象析構程序運行后顯示:程序運行后顯示: function3function3中發生異常中發生異常 在在function1function1和和fuction2fuction2中分別定義了中分別定義了ForTestForTest類的對象。如果函數可以正常退出,這些對象類的對象。如果函數可以正常退出,這些對象將被釋放。將被釋放。 但是,程序運行后只顯示了異常信息。沒有析但是,程序運行后只顯示了異常信息。沒有析構函數被調用的跡象。說明所創建的對象沒

50、有構函數被調用的跡象。說明所創建的對象沒有被釋放。被釋放。 如果采用如果采用C+C+的異常處理機制來進行處理。情的異常處理機制來進行處理。情況就會完全不同。況就會完全不同。 2022-4-14北京郵電大學電信工程學院計算機技術中心-50-13.4異常處理中的退棧和對象析構異常處理中的退棧和對象析構如果在如果在function3function3中用中用throwthrow語句來拋擲語句來拋擲異常,就會開始異常,就會開始function3function3的退棧。的退棧。 然后,返回到函數然后,返回到函數function2function2開始開始function2function2的退棧,并且調用的退棧,并且調用ForTestForTest類析構函數,釋放對象類析構函數,釋放對象A12A12。 接著,返回到函數接著,返回到函數function1function1開始開始function1function1的退棧,并且調用的退棧,并且調用ForTestForTest類析構函數,釋放對象類析構函數,釋放對象A11A11。 2022-4-14北京郵電大學電信工程學院計算機技術中心-51-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論