Microsoft PowerPoint - 13_Exception.ppt

Similar documents
Microsoft PowerPoint - 11_Templates.ppt

新版 明解C++入門編

C++ 程式設計

chp6.ppt

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

c_cpp

untitled

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d

1: public class MyOutputStream implements AutoCloseable { 3: public void close() throws IOException { 4: throw new IOException(); 5: } 6:

ebook39-5

投影片 1

第二章 簡介類別

Microsoft Word - 01.DOC

Microsoft PowerPoint - ch15.ppt

FY.DOC

ebook39-6

2013 C 1 #include <stdio.h> 2 int main(void) 3 { 4 int cases, i; 5 long long a, b; 6 scanf("%d", &cases); 7 for (i = 0; i < cases; i++) 8 { 9 scanf("%

untitled

Microsoft PowerPoint - Class5.pptx

全国计算机技术与软件专业技术资格(水平)考试

3. 企 业 债 券 : 公 司 债 券 : 5. 证 券 公 司 债 券 : 6. 企 业 短 期 融 资 券 : 7. 中 期 票 据 : 8. 资 产 支 持 证 券 : 9. 国 际 开 发 机 构 人 民 币 债 券 : 10. 中 小 非 金 融 企 业 集 合 票 据 例 题? 判 断

運算子多載 Operator Overloading

優質居所 攜手共建

《大话设计模式》第一章

untitled

untitled

C/C++语言 - C/C++数据

Microsoft PowerPoint - EmbSys101_Java Basics.ppt [相容模式]

CC213

第3章.doc

運算子多載 Operator Overloading

第七讲 继承与多态

踏出C++的第一步

untitled

Microsoft Word cppFinalSolution.doc

chap07.key

Strings

Microsoft Word - PHP7Ch01.docx

3.1 num = 3 ch = 'C' 2

任務二 : 產生 20 個有炸彈的磚塊, 放在隨機的位置編輯 Block 類別的程式碼 import greenfoot.; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) Write a description of class

單步除錯 (1/10) 打開 Android Studio, 點選 Start a new Android Studio project 建立專案 Application name 輸入 BMI 點下 Next 2 P a g e

Java

Microsoft PowerPoint - 09_Inheritance.ppt

untitled

¬¬

2 WF 1 T I P WF WF WF WF WF WF WF WF 2.1 WF WF WF WF WF WF

Strings

untitled

Python a p p l e b e a r c Fruit Animal a p p l e b e a r c 2-2






The golden pins of the PCI card can be oxidized after months or years

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

Microsoft PowerPoint - ch11.ppt

Microsoft PowerPoint - 13_ClassAndObj.ppt

C/C++ 语言 - 循环

Microsoft Word - ch04三校.doc

内 容 提 要 指 针 持 久 动 态 内 存 分 配 字 符 串 ( 字 符 数 组 ) 2

untitled

Spyder Anaconda Spyder Python Spyder Python Spyder Spyder Spyder 開始 \ 所有程式 \ Anaconda3 (64-bit) \ Spyder Spyder IPython Python IPython Sp

Chapter 8 - Operator Overloading

2002 Shintoukai Chinese Academy. All rights reserved 2

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C Project 30 C Project 3 60 Project 40

文档 3

試卷一

untitled

Microsoft PowerPoint - L17_Inheritance_v4.pptx

運算子多載 Operator Overloading

陳偉補習班環境介紹

<30312E20B9EFB7C5AF66BEC7A4A4A175A5CDAC7ABE69B3B1A176AABABDD7AA522E706466>

Chapter12 Derived Classes

EJB-Programming-4-cn.doc

Microsoft Word - 11.doc

CC213

<32372E20B077A8EBABE1B7CBA5DEA4A3A650B260ABD7B9EFAA76C0F8AFABB867AEDAABACC056B4D5AF66AABAC0F8AEC4B1B4AFC12E706466>

Microsoft PowerPoint - P766Ch06.ppt

2/80 2

mvc


Scott Effective C++ C++ C++ Roger Orr OR/2 ISO C++ Effective Modern C++ C++ C++ Scoot 42 Bart Vandewoestyne C++ C++ Scott Effective Modern C++ Damien

China Academic Journal Electronic Publishing House. All rights reserved.

China Academic Journal Electronic Publishing House. All rights reserved.


幻灯片 1


目 录 欢 迎 使 用 产 品 介 绍 产 品 概 述 产 品 特 点 代 理 商 系 统 使 用 说 明 登 陆 基 本 信 息 分 销 商 管 理 帐 户

Chapter 9: Objects and Classes


EJB-Programming-3.PDF

Microsoft Word - ACL0204-ch11-ok.doc

Microsoft Word - 投影片ch13

提问袁小兵:


untitled


(6) 要 求 付 款 管 理 员 从 预 订 表 中 查 询 距 预 订 的 会 议 时 间 两 周 内 的 预 定, 根 据 客 户 记 录 给 满 足 条 件 的 客 户 发 送 支 付 余 款 要 求 (7) 支 付 余 款 管 理 员 收 到 客 户 余 款 支 付 的 通 知 后, 检

目 录 第 一 部 分 档 案 局 概 况 一 主 要 职 责 二 部 门 决 算 单 位 构 成 第 二 部 分 档 案 局 2016 年 度 部 门 预 算 表 一 2016 年 度 市 级 部 门 收 支 预 算 总 表 二 2016 年 度 市 级 部 门 支 出 预 算 表 三 2016

Transcription:

1 第 13 章例外處理 (Exception Handling) 13.1 簡介 13.2 例外處理概觀 13.3 其它錯誤處理技術 13.4 簡單的例外處理範例 - 除 0 錯誤 13.5 重新丟出例外 13.6 函式例外清單 13.7 處理非預期例外 13.8 堆疊返回 13.9 建構子, 解構子, 與例外處理 13.10 例外與繼承 13.11 處理新的錯誤 13.12 auto_ptr 類別與動態記憶體配置

2 13.1 簡介 例外 表示程式出問題 發生不正常情況 程式停止執行 例外處理 解決例外情況 程式可以繼續執行 - 可容許錯誤 例如 : 可處理程式除 0 錯誤

3 13.2 例外處理概觀 術語 (Terminology) 丟出例外 (throws an exception) 函式遇到錯誤 例外處理程式 (Exception handler) 捕捉及處理例外 假如沒有例外處理程式捕捉適當例外 程式將可能中斷執行

4 13.2 例外處理概觀 C++ 程式 try { 可能丟出例外的程式碼使用 throw 丟出例外, 可丟出任何資料型態的物件通常丟出 exception 物件 } catch (exceptiontype1){ 處理例外的程式碼 } catch (exceptiontype2){... }

5 13.4 簡單的例外處理範例 : 除 0 錯誤 例外類別 基礎類別 exception, 引用 <exception> 建構子可接受一個字串 用來描述例外 成員函式 what() 會傳回該字串 衍生類別 runtime_error, logic_error bad_alloc, bad_cast, bad_typeid

6 13.2 例外處理概觀 捕捉所有例外類別 catch (...) catch (exception &anyexception) 捕捉特定例外類別 catch (MyException &myex) catch ( bad_alloc &memallocationex ) catch ( runtime_error &error )

7 13.2 例外處理概觀 在 try 區塊內 假如發生例外 程式會跳過 try 區塊內還沒執行的程式 進入適當的 catch 區塊 假如沒有例外處理程式可用 函式結束 尋找較上層的 catch 區塊 如果沒有例外 執行完 try 區塊 跳過 catch 區塊

8 13.3 其它錯誤處理技術 忽略例外 - 程式可能不正常結束 終止程式執行 設定錯誤指示燈 呼叫 exit () - <cstdlib> 跳到外層處理錯誤 - 破壞程式結構 setjump and longjump - <csetjmp> 專屬的錯誤處理程式 例如 : new 有專屬錯誤處理程式

9 13.4 簡單的例外處理範例 : 除 0 錯誤 範例程式 定義新的例外類別 DivideByZeroException 繼承 exception 類別 處理除 0 錯誤

10 13.4 簡單的例外處理範例 : 除 0 錯誤 在除法函式中 測試分母 假如分母為零, 丟出例外 在 try 區塊內 呼叫除法函式 catch DivideByZeroException 例外物件 遇到除 0 錯誤, 程式可繼續執行

1 // Fig. 13.1: fig13_01.cpp 2 // 一個簡單的例外處理範例程式 3 // 用來檢查除 0 例外 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 10 #include <exception> 11 12 using std::exception; 13 14 // 定義一個例外類別 :DivideByZeroException 15 // 當發生除 0 錯誤時可丟出此類例外 16 class DivideByZeroException : public exception { 17 18 public: 19 20 // 建構子 : 直接實作, 指定錯誤訊息 21 DivideByZeroException::DivideByZeroException() 22 : exception( "attempted to divide by zero" ) {} 23 24 }; // end class DivideByZeroException 25 Outline fig13_01.cpp (1 of 3) 2003 Prentice Hall, Inc. All rights reserved. 11

26 // 執行除法動作 27 // 如果除數為 0, 則丟出 DivideByZeroException 物件 28 double quotient( int numerator, int denominator ) 29 { 30 // 假如除數為 0 丟出 DivideByZeroException 例外並結束此函式 31 if ( denominator == 0 ) 32 throw DivideByZeroException(); // 丟出例外並結束函式執行 33 34 // 傳回除法運算結果 35 return static_cast< double >( numerator ) / denominator; 36 37 } // end function quotient 38 39 int main() 40 { 41 int number1; // 使用者指定的被除數 42 int number2; // 使用者指定的除數 43 double result; // 除法運算結果 44 45 cout << "Enter two integers (end-of-file to end): "; 46 Outline fig13_01.cpp (2 of 3) 12 2003 Prentice Hall, Inc. All rights reserved.

47 // 要求使用者輸入被除數與除數 48 while ( cin >> number1 >> number2 ) { 49 50 // try 區塊內含可能傳回例外的程式碼 51 // 以及當例外發生時不應執行的程式碼 52 try { 53 result = quotient( number1, number2 ); 54 cout << "The quotient is: " << result << endl; 55 56 } // end try 57 58 // 例外處理程式 : 處理除 0 例外 59 catch ( DivideByZeroException &dividebyzeroexception ) { 60 cout << "Exception occurred: " 61 << dividebyzeroexception.what() << endl; 62 63 } // end catch 64 65 cout << "\nenter two integers (end-of-file to end): "; 66 67 } // end while 68 69 cout << endl; 70 71 return 0; // 正常結束 72 73 } // end main Outline fig13_01.cpp (3 of 3) 2003 Prentice Hall, Inc. All rights reserved. 13

Enter two integers (end-of-file to end): 100 7 The quotient is: 14.2857 Enter two integers (end-of-file to end): 100 0 Exception occurred: attempted to divide by zero Enter two integers (end-of-file to end): ^Z Outline fig13_01.cpp output (1 of 1) 14 2003 Prentice Hall, Inc. All rights reserved.

15 13.5 重新丟出例外 重新丟出例外 當例外處理程式不能完全處理例外時 處理一部份, 再重新丟出 上層的 try 區塊與相對應的 catch 區塊會處理 要重新丟出例外 使用指令 "throw;" 不需參數 結束函式執行

1 // Fig. 13.2: fig13_02.cpp 2 // 重新丟出例外範例程式 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <exception> 9 10 using std::exception; 11 12 // throw, catch and rethrow exception 13 void throwexception() 14 { 15 // 丟出例外並利用 catch 捉住例外 16 try { 17 cout << " Function throwexception throws an exception\n"; 18 throw exception(); // 產生例外 19 20 } // end try 21 22 // 處理例外 23 catch ( exception &caughtexception ) { 24 cout << " Exception handled in function throwexception" 25 << "\n Function throwexception rethrows exception"; 26 27 throw; // 重新丟出例外 28 29 } // end catch Outline fig13_02.cpp (1 of 2) 2003 Prentice Hall, Inc. All rights reserved. 16

30 31 cout << "This also should not print\n"; 32 33 } // end function throwexception 34 35 int main() 36 { 37 // 丟出例外 38 try { 39 cout << "\nmain invokes function throwexception\n"; 40 throwexception(); 41 cout << "This should not print\n"; 42 43 } // end try 44 45 // 處理例外 46 catch ( exception &caughtexception ) { 47 cout << "\n\nexception handled in main\n"; 48 49 } // end catch 50 51 cout << "Program control continues after catch in main\n"; 52 53 return 0; 54 55 } // end main Outline fig13_02.cpp (2 of 2) 2003 Prentice Hall, Inc. All rights reserved. 17

main invokes function throwexception Function throwexception throws an exception Exception handled in function throwexception Function throwexception rethrows exception Exception handled in main Program control continues after catch in main Outline fig13_02.cpp output (1 of 1) 18 2003 Prentice Hall, Inc. All rights reserved.

19 13.6 函式例外清單 列出函式可能丟出的例外 例外丟出清單 int somefunction( double value ) throw ( ExceptionA, ExceptionB, ExceptionC ) { // function body } 函式只能丟出例外 ExceptionA, ExceptionB, ExceptionC 或以上例外的衍生類別 如果丟出其它例外, 會呼叫 unexpected 函式

20 13.6 函式例外清單 沒有例外丟出清單 可丟出任何種類例外 例外丟出清單沒列任何例外 不能丟出例外

21 13.7 處理非預期 (unexpected) 例外 unexpected 函式 利用 set_unexpected 函式 <exception> 預設值會終止程式執行 set_terminate 設定處理函式 函式沒有輸入 傳回值為 void 預設函式 :abort 如果有設定處理函式, 處理函式執行完也會呼叫 abort

22 13.8 堆疊返回 如果例外被丟出但是沒有被捉住 結束目前函式 清除函式呼叫堆疊 搜尋可處理例外的 try/catch 如果沒有找到則再回到上一層 假如例外都沒被捉住 結束程式執行

1 // Fig. 13.3: fig13_03.cpp 2 // 堆疊重返說明範例程式. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <stdexcept> // 使用 runtime_error 例外 9 10 using std::runtime_error; 11 12 // function3 丟出 runtime_error 例外 13 void function3() throw ( runtime_error ) 14 { 15 throw runtime_error( runtime_error in function3 ); // 4 16 } 17 18 // function2 呼叫 function3 19 void function2() throw ( runtime_error ) 20 { 21 function3(); // 3 22 } 23 Outline fig13_03.cpp (1 of 2) 23 2003 Prentice Hall, Inc. All rights reserved.

24 // function1 呼叫 function2 25 void function1() throw ( runtime_error ) 26 { 27 function2(); // 2 28 } 29 30 // 主程式 31 int main() 32 { 33 // 呼叫 function1 34 try { 35 function1(); // 1 36 37 } // end try 38 39 // 處理 runtime_error 40 catch ( runtime_error &error ) // 5 41 { 42 cout << "Exception occurred: " << error.what() << endl; 43 44 } // end catch 45 46 return 0; 47 48 } // end main Outline fig13_03.cpp (2 of 2) 24 Exception occurred: runtime_error in function3 2003 Prentice Hall, Inc. All rights reserved.

25 13.9 建構子, 解構子, 與例外處理 建構子內的錯誤 new 失敗 ; 不能配置記憶體 程式直接終止, 無法呼叫解構子 解決方法 : Increment::Increment( int c, int i ) { try { ary1=new int[c]; ary2=new int[c]; } catch(...) { delete this; throw; } } // end constructor Increment

26 13.9 建構子, 解構子, 與例外處理 成員函式的錯誤 物件型態 MyClass myclass(...); 物件結束前會自動呼叫解構子 物件指標 MyClass *myclassptr=new MyClass(...); 例外情況可能無法 delete 物件 可將物件指標宣稱成自動指標 auto_ptr

27 13.10 例外與繼承 例外類別 可繼承基礎例外類別 I.e., exception 用 catch 捕捉基礎類別也能捕捉衍生類別 多型程式設計

28 13.11 處理 new 失敗情形 當 new 失敗時 丟出 bad_alloc 例外 定義在 <new> 某些編譯器會讓 new 傳回 0 結果跟編譯器有關

1 // Fig. 13.4: fig13_04.cpp 2 // 範例程式 3 // 說明 new 發生錯誤時會傳回 0 4 #include <iostream> 5 6 using std::cout; 7 8 int main() 9 { 10 double *ptr[ 50 ]; 11 12 // 配置記憶體給 ptr 13 for ( int i = 0; i < 50; i++ ) { 14 ptr[ i ] = new double[ 5000000 ]; 15 16 // 配置記憶體失敗 new 會傳回 0 17 if ( ptr[ i ] == 0 ) { 18 cout << "Memory allocation failed for ptr[ " 19 << i << " ]\n"; 20 21 break; 22 23 } // end if 24 Outline fig13_04.cpp (1 of 2) 2003 Prentice Hall, Inc. All rights reserved. 29

25 // 成功配置記憶體 26 else 27 cout << "Allocated 5000000 doubles in ptr[ " 28 << i << " ]\n"; 29 30 } // end for 31 32 return 0; 33 34 } // end main Outline fig13_04.cpp (2 of 2) fig13_04.cpp output (1 of 1) 30 Allocated 5000000 doubles in ptr[ 0 ] Allocated 5000000 doubles in ptr[ 1 ] Allocated 5000000 doubles in ptr[ 2 ] Allocated 5000000 doubles in ptr[ 3 ] Memory allocation failed for ptr[ 4 ] 2003 Prentice Hall, Inc. All rights reserved.

1 // Fig. 13.5: fig13_05.cpp 2 // 範例程式 - 使用標準 new 函式 3 // 說明 new 失敗會丟出 bad_alloc 例外 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 #include <new> // 引用 new 標頭檔 10 11 using std::bad_alloc; // 使用 bad_alloc 例外 12 13 int main() 14 { 15 double *ptr[ 50 ]; 16 17 // 嘗試配置記憶體 18 try { 19 20 // 配置記憶體給 ptr[ i ]; new throws bad_alloc 21 // 失敗 :new 會丟出 bad_alloc 例外 22 for ( int i = 0; i < 50; i++ ) { 23 ptr[ i ] = new double[ 5000000 ]; 24 cout << "Allocated 5000000 doubles in ptr[ " 25 << i << " ]\n"; 26 } 27 28 } // end try Outline fig13_05.cpp (1 of 2) 2003 Prentice Hall, Inc. All rights reserved. 31

29 30 // 處理 bad_alloc 例外 31 catch ( bad_alloc &memoryallocationexception ) { 32 cout << "Exception occurred: " 33 << memoryallocationexception.what() << endl; 34 35 } // end catch 36 37 return 0; 38 39 } // end main Outline fig13_05.cpp (2 of 2) fig13_05.cpp output (1 of 1) 32 Allocated 5000000 doubles in ptr[ 0 ] Allocated 5000000 doubles in ptr[ 1 ] Allocated 5000000 doubles in ptr[ 2 ] Allocated 5000000 doubles in ptr[ 3 ] Exception occurred: Allocation Failure 2003 Prentice Hall, Inc. All rights reserved.

33 13.11 處理 new 失敗情形 set_new_handler 標頭檔 <new> 設定一個函式處理 new 的錯誤 沒有輸入參數 傳回值 :void 輸入參數 : 函式指標 設定完, new 失敗會呼叫此函式, 不丟出例外 範例程式

1 // Fig. 13.6: fig13_06.cpp 2 // set_new_handler 使用範例 3 #include <iostream> 4 5 using std::cout; 6 using std::cerr; 7 8 #include <new> // 引用 new 9 10 using std::set_new_handler; 11 12 #include <cstdlib> // 引用 abort 函式原型 13 14 void customnewhandler() 15 { 16 cerr << "customnewhandler was called"; 17 abort(); 18 } 19 20 // 使用 set_new_handler 處理記憶體配置失敗 21 int main() 22 { 23 double *ptr[ 50 ]; 24 Outline fig13_06.cpp (1 of 2) 2003 Prentice Hall, Inc. All rights reserved. 34

25 // 指定 customnewhandler 函式, 26 // 處理記憶體配置失敗 27 set_new_handler( customnewhandler ); 28 29 // 配置記憶體給 ptr[ i ] 30 // 記憶體配置失敗時 customnewhandler 會被呼叫 31 for ( int i = 0; i < 50; i++ ) { 32 ptr[ i ] = new double[ 5000000 ]; 33 34 cout << "Allocated 5000000 doubles in ptr[ " 35 << i << " ]\n"; 36 37 } // end for 38 39 return 0; 40 41 } // end main Outline fig13_06.cpp (2 of 2) fig13_06.cpp output (1 of 1) 35 Allocated 5000000 doubles in ptr[ 0 ] Allocated 5000000 doubles in ptr[ 1 ] Allocated 5000000 doubles in ptr[ 2 ] Allocated 5000000 doubles in ptr[ 3 ] customnewhandler was called 2003 Prentice Hall, Inc. All rights reserved.

36 13.12 auto_ptr 類別與動態記憶體配置 宣稱指標, 使用 new 配置記憶體 例外發生在 delete 之前會導致 - Memory leak 類別樣版 auto_ptr 標頭檔 <memory> 當指標超出範圍, 自動呼叫 delete 用法 auto_ptr< MyClass > newpointer( new MyClass() ); newpointer 會指到動態配置的物件

1 // Fig. 13.7: fig13_07.cpp 2 // auto_ptr 使用範例 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <memory> // 使用 auto_ptr 9 10 using std::auto_ptr; // 使用 auto_ptr 類別定義 11 12 class Integer { 13 14 public: 15 16 // 建構子 17 Integer( int i = 0 ) 18 : value( i ) 19 { 20 cout << "Constructor for Integer " << value << endl; 21 22 } // end Integer constructor 23 Outline fig13_07.cpp (1 of 3) 37 2003 Prentice Hall, Inc. All rights reserved.

24 // 解構子 25 ~Integer() 26 { 27 cout << "Destructor for Integer " << value << endl; 28 29 } // end Integer destructor 30 31 // 設定 value 的值 32 void setinteger( int i ) 33 { 34 value = i; 35 36 } // end function setinteger 37 38 // 傳回 value 的值 39 int getinteger() const 40 { 41 return value; 42 43 } // end function getinteger 44 45 private: 46 int value; 47 48 }; // end class Integer 49 Outline fig13_07.cpp (2 of 3) 2003 Prentice Hall, Inc. All rights reserved. 38

50 // 使用 auto_ptr 操作 Integer 物件 51 int main() 52 { 53 cout << "Creating an auto_ptr object that points to an " 54 << "Integer\n"; 55 56 // 令 auto_ptr 指到 Integer 物件 57 auto_ptr< Integer > ptrtointeger( new Integer( 7 ) ); 58 59 cout << "\nusing the auto_ptr to manipulate the Integer\n"; 60 61 // 使用 auto_ptr 設定 Integer 的值 62 ptrtointeger->setinteger( 99 ); 63 64 // 使用 auto_ptr 取得 Integer 的值 65 cout << "Integer after setinteger: " 66 << ( *ptrtointeger ).getinteger() 67 << "\n\nterminating program" << endl; 68 69 return 0; 70 71 } // end main Outline fig13_07.cpp (3 of 3) 39 2003 Prentice Hall, Inc. All rights reserved.

Creating an auto_ptr object that points to an Integer Constructor for Integer 7 Using the auto_ptr to manipulate the Integer Integer after setinteger: 99 Outline fig13_07.cpp output (1 of 1) 40 Terminating program Destructor for Integer 99 2003 Prentice Hall, Inc. All rights reserved.