service-side: throw Exceptions client-side: try-and-catch

Slides:



Advertisements
Similar presentations
1 第 3 章 C++ 中的条件与循环 第 3 次见面! acm.nefu.edu.cn/C++_03.ppt.
Advertisements

单元二:面向对象程序设计 任务二:借书卡程序设计.
第四章 类、对象和接口.
第一單元 建立java 程式.
本校學生兼任助理 相關規定和行政作業流程 104年9月2日 人事室.
第九讲 类与对象 (I)面向对象基础.
第二章 JAVA语言基础.
第八章 类和对象.
C++程序设计 王希 图书馆三楼办公室.
第十一章 (上篇) 函數樣板(Function Template) 與 類別樣板(Class Template)
C# 程式設計 第一部分 第1-4章 C# 程式設計 - 南華大學資管系.
例外處理(Exception Handling)
4.1 概述 4.2 类与对象的实现 4.3 对象的初始化和析构 4.4 类的包含 4.5 类模板
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
第2章回顾 标识符:不用记,动手 关键字:if, else, switch, for, while, do, break, continue, void, …… 局部变量和成员变量 ①变量作用域 ②内存布局 基本数据类型 ①4类8种 ②互相转换 流程控制语句 ①分支 if……else, switch.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Object-Oriented Programming in C++ 第一章 C++的初步知识
第三章 C++中的C 面向对象程序设计(C++).
第12章 從C到C++語言 12-1 C++語言的基礎 12-2 C++語言的輸出與輸入 12-3 C++語言的動態記憶體配置
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
程式撰寫流程.
Java语言程序设计 第五部分 Java异常处理.
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
第四章 小技巧.
例外處理與 物件序列化(Exception Handling and Serialization of Objects)
檔案讀寫與例外處理 (File IO and Exception Handling)
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
异常及处理.
程序的三种基本结构 if条件分支语句 switch多路开关语句 循环语句 循环嵌套 break,continue和goto语句
Java程序设计 第2章 基本数据类型及操作.
第5讲 使用类和对象编程(三) 内部类 实例 程序控制结构 选择语句.
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
P2P聊天工具.
編譯程式設計 期末專題說明 V1.1 May 2004.
第一單元 建立java 程式.
第16章 虛擬與多形 16-1 虛擬函數 16-2 純虛擬函數與抽象類別 16-3 多形 16-4 虛擬繼承與虛擬解構子.
10 多載函數 10.1 多載概論 多載一般函數 多載成員函數 10-3
《JAVA程序设计》 语音答疑 辅导老师:高旻.
常宝宝 北京大学计算机科学与技术系 数据结构(三) 常宝宝 北京大学计算机科学与技术系
第二章Java基本程序设计.
C++语言程序设计 C++语言程序设计 第五章 函数 第十一组 C++语言程序设计.
程式結構&語法.
Java變數 2014/6/24.
4 條件選擇 4.1 程式基本結構 循序式結構 選擇式結構 重複式結構 4-3
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
Oop8 function函式.
第二章 Java基本语法 讲师:复凡.
C++程式設計入門 變數與運算子 作者:黃建庭.
第二章 Java语法基础.
C++程序设计 吉林大学计算机科学与技术(软件)学院.
第二章 类型、对象、运算符和表达式.
Review 1~3.
第九章 物件導向-進階.
C/C++基礎程式設計班 C++: 物件的使用、參考、重載函式 講師:林業峻 CSIE, NTU 3/28, 2015.
第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
Java程序设计 第17章 异常和断言.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
本章主題 C++的程式結構 資料型態與宣告 算術運算 簡易的輸入輸出指令 程式編譯(Compile)的過程與原理.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
第四章 陣列、指標與參考 4-1 物件陣列 4-2 使用物件指標 4-3 this指標 4-4 new 與 delete
C++面向对象程序设计 谭浩强编著 授课教师:姬广永 学习网站:
第2章 Java语言基础.
第4讲 类和对象、异常处理 ggao.
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
變數與資料型態  綠園.
第二章 Java基础语法 北京传智播客教育
方法(Method) 函數.
Presentation transcript:

service-side: throw Exceptions client-side: try-and-catch 第十一章 (下篇) 例外處理 service-side: throw Exceptions client-side: try-and-catch

客戶端與服務端程式 要求服務 客戶端程式 服務端程式 main(): circle_area() 呼叫circle_area() 傳回結果 錯誤(例外,非正常)狀況發生時雙方的權責??

例外處理(Exception Handling) double circle_area(int r) { if (r<0) {return –1 ;} return 3.14*r*r; } void main() { double r ; cin >> r ; double a = circle_area(r) ; if (a == -1) { /*錯誤處理 */ } else cout << a << endl ; }

例外處理 double circle_area(double r, bool& suc) { if (r<0) {cout << “r<0”; suc = false ;} suc = true ; return 3.14*r*r; } void main() { double r ; bool suc; cin >> r ; double a = circle_area(r, suc) ; if (suc == false) { /*錯誤處理 */ } else cout << a << endl ; }

例外處理 double circle_area(double r, int& error_code) { if (r <0) error_code = 1 ; if (r==0) error_code = 2 ; error_code = 0 ; return 3.14*r*r; } void main() { double r ; int error_code; cin >> r ; double a = circle_area(r, error_code) ; if (error_code == 0) cout << a << endl ; else if (error_code == 1) { /*錯誤處理 */ } else if ......

例外處理 double circle_area(double r) { if (r<0) { cout << “circle(): r<0”; exit(1) ; } return 3.14*r*r; } void main() { double r ; cin >> r ; cout << circle_area(r) <<endl ;

缺點 錯誤發生時,服務端程式通知客戶端程式的方式千奇百怪,使用者窮於應付 服務端程式有時也參與錯誤處理,權責不清 縱使權責清楚,客戶端程式也將因處理錯誤而使可讀性大大降低

可讀性降低 // 完全無例外處理 void main() { double r, w, h, ta=0 ; cin>>r>>w>>h ; ta = circle_area(r) + rectangle_area(w,h); cout << “result=“ << ta <<endl; }  加上例外處理的結果

可讀性大幅降低 void main() { double r, w, h, ta=0 ; bool suc ; cin >> r>>w>>h; double a = circle_area(r, suc) ; if ( suc) { ta += a; } else {cout << “error”; } a = rectangle_area(w, h) ; if (a == -1) { ....} else if (a == -2) {...} else if {ta += a; } cout << “result=“ << ta <<endl ; }

結論 平心而論,完全沒有錯誤處理的程式不論在發展時期或執行時期都將造成困擾。 錯誤處理既是必要的,是否有明確而一致的方式? C++, Java 客戶端: try-catch, 服務端: throw

例外發生時的權責 客戶端程式 main() 服務端程式 circle_area() 要求服務 提供服務 發出例外(錯誤)訊息 接收、處理例外

C++例外處理: 使用前 double circle_area(double r, int& error_code) { if (r<0) error_code = -1 ; error_code = 0 ; return r*r*3.14 ; } void main() { double r ; cin >> r ; int error_code ; double a = circle_area(r, error_code) ; if (error_code == -1) cout << “error, code=“ << x <<endl ; else cout << a <<endl ; cout << “End of Program” <<endl ;

throw, try-and-catch 負責丟出例外訊息 負責接收及處理例外 double circle_area(double r) throw (int) { if (r<0) { throw –1; } return r*r*3.14 ; } void main() { double r,a ; cin >> r ; try { a = circle_area(r) ; cout << a <<endl ; } catch (int x) { cout << “error, code=“ << x <<endl ; cout << “End of Program” <<endl ; 負責接收及處理例外

正常狀況下的執行次序 1 double circle_area(double r) throw (int) { 2 if (r<0) { throw –1; } 3 return r*r*3.14 ; 4 } 5 void main() { 6 double r,a ; cin >> r ; // 5 7 try { 8 a = circle_area(r) ; 9 cout << a <<endl ; 10 } catch (int x) { 11 cout << “error, code=“ << x <<endl ; 12 } 13 cout << “End of Program” <<endl ; 14 } 5, 6, 7, 8, 1, 2, 3, 9, 13

例外發生時的執行次序 1 double circle_area(double r) throw (int) { 2 if (r<0) { throw –1; } 3 return r*r*3.14 ; 4 } 5 void main() { 6 double r, a ; cin >> r ; // -5, 故意讓circle_area產生例外 7 try { 8 a = circle_area(r) ; //發生例外狀況 9 cout << a <<endl ; 10 } catch (int x) { 11 cout << “error, code=“ << x <<endl ; 12 } 13 cout << “End of Program” <<endl ; 14 } 5, 6, 7, 8, 1, 2, 10, 11, 12 ,13

EX: 例外發生時以下二程式的輸出有何不同 void main() { double r,a ; cin >> r ; try { a = circle_area(r) ; cout << a <<endl ; } catch (int x) { cout << x <<endl ; } cout << “End of Program” <<endl ; void main() { double r,a ; cin >> r ; try { a = circle_area(r) ; } catch (int x) { cout << x <<endl ; } cout << a <<endl ; cout << “End of Program” <<endl ;

討論 try block中至少該放入甚麼? 需要接收例外的程式碼 void main() { double r ; cin >> r ; double a1 = circle_area(r) ; //可能產生例外 double w, h ; cin >> w >> h ; double a2 = rectangle_area(w,h);//可能產生例外 cout << a1+a2<<endl ; }

討論(續) void main() { try { double r,a1,a2 ; cin >> r ; a1 = circle_area(r) ; }catch (int x) { // ... 錯誤處理 } double w, h ; cin >> w >> h ; a2 = rectangle_area(w,h); }catch(int y) { cout << a1+a2<<endl ; void main() { try { double r,a1,a2 ; cin >> r ; a1 = circle_area(r) ; double w, h ; cin >> w >> h ; a2= rectangle_area(w,h); cout << a1+a2<<endl ; }catch(int x) { // ... 錯誤處理 }

EX: 例外型態判別-使用錯誤碼 double circle_area(double r) throw (int) { if (r<0) { throw –1; } return r*r*3.14 ; } double rectangle_area(int w, int h) throw (int) { if (w<0 && h<0) throw –2 ; if (w<0 || h < 0) throw –3 ; return w*h ; void main() { double r, w, h, a = 0 ; try { cin >> r >> w >> h ; a = circle_area(r) + rectangle_area(w,h); } catch (int x) { switch(x) { case –1: .... case –2: .... } cout << “area=“ << endl ;

EX:例外型態判別-使用資料型態 - 探討各種例外發生時程式執行的次序 double circle_area(double r) throw (int) { if (r<0) { throw –1; } return r*r*3.14 ; } double rectangle_area(int w, int h) throw (char, double) { if (w<0 && h<0) throw ‘a’ ; if (w<0 || h < 0) throw 3.14 ; return w*h ; void main() { double r, w, h, a = 0 ; try { cin >> r >> w >> h ; a = circle_area(r) + rectangle_area(w,h); } catch (int x) { // circle_area()中的錯誤 } catch (char c) { // rectangle_area()中的錯誤 } catch (double d) { } cout << “area=“ << endl ;

練習: 考慮overflow, underflow int data[10], top = -1 ; void push(int x) { data[++top]=x ; } int pop() { return data[top--] ; void main() { int n, i ; cin >> n ; for (i = 0 ; i<n; i++) push(n) ; for (i=0; i<n; i++) cout << pop() ; }

練習: 改成class stack void main() { class stack{ stack s; int n, i ; cin >> n ; try { for (i = 0; i<n; i++) { s.push(i) ; } s.show(); for (i=0; i<n; i++) { cout << s.pop() <<endl; catch(int x) if(x==-1) { cout<<"overflow"<<endl;} if(x==-2) { cout<<"underflow"<<endl;} //show(); getch(); class stack{ int data[10], top; public: stack(){top=-1;} void push(int x) throw (int) { if(x>9) throw -1; } data[++top]=x ; int pop() throw (int) if(top<0) throw -2; return data[top--] ; void show() for(int i=0;i<top+1;i++) cout<<data[i]<<endl; };

EX: 故意不接例外 void main() { stack s; for (int i = 0 ; i <20 ; i++) s.push(i) ; //可能產生例外 }

EX: 沒接到 double circle_area(double r) throw (int) { if (r<0) { throw –1; } return r*r*3.14 ; } void main() { try { ...... circle_area(r) ; } catch (char c) {

討論 每個函數都使用throw (int) throw (int, double, float...) 延續錯誤碼概念: 大家共用容易弄錯 延續錯誤碼概念: 大家共用容易弄錯 throw (int, double, float...) 時而有窮.....  丟回自訂類別

丟出自訂類別: 服務端 class Exception { public: string description ; Exception(string s) { description = s ; } } ; double circle_area(double r) throw (Exception){ if (r < 0) throw Exception(“circle_area(): r<0”) ; return r*r*3.14 ; } Exception e(“circle_area(): r<0”); throw e ;

接收自訂類別: 客戶端 void main() { try { ... circle_area(r) ; } catch (Exception e) { cout << e.description <<endl ; // 錯誤處理, maybe exit(1) ; }

每個函數均自訂例外型態 class CircleException: public Exception { public: CircleException(string s): Exception(s) { } } ; class RectException: public Exception { public: RectException(string s): Exception(s) { } double circle_area(double r) throw (CircleException) { if (r < 0) throw CircleException(“circle, r<0”) ; return 3.14 * r * r ; } double rectangle_area(double w, double h) throw (RectException) { if (w<0||h<0) throw RectException(“Rect, w<0 || h<0”) ; return w*h ;

練習: 客戶端程式 void main() { double r, w, h ; cin >> r >> w >> h ; cout << circle_area(r) <<endl ; cout << rectangle_area(r) <<endl ; }

客戶端程式:使用繼承概念 void main() { int r, w, h ; cin >> r >> w >> h ; try { cout << circle_area(r) <<endl ; cout << rectangle_area(w, h) <<endl ; } catch (Exception e) { cout << e.description <<endl ; }

catch(...) void main() { try { void fun1() throw (int) { fun1(); fun2(); fun3(); } catch (int) { //例外處理 } catch (char) { // 例外處理 } catch(double) { } void fun1() throw (int) { throw 1 ; } void fun2() throw (char) { throw ‘a’ ; void fun3() throw (double) { throw 3.14 ;

catch(...)使用範例 void main() { try { void fun1() throw (int) { fun1(); fun2(); fun3(); } catch (...) { //例外處理 } void fun1() throw (int) { throw 1 ; } void fun2() throw (char) { throw ‘a’ ; void fun3() throw (double) { throw 3.14 ;

catch(...)使用範例 void main() { try { void fun1() throw (int) { fun1(); fun2(); fun3(); } catch (int x) { //例外處理 } catch (...) { //其他例外 } void fun1() throw (int) { throw 1 ; } void fun2() throw (char) { throw ‘a’ ; void fun3() throw (double) { throw 3.14 ;

巢狀例外處理 把不能處理的例外再丟出去