第6章 异常处理 陈哲 副教授 南京航空航天大学 计算机科学与技术学院
6.1 异常 float divide(int numer, int div ) { if ( div == 0 ) 6.1 异常 异常是在程序执行期间的突发性事件。 异常与错误不同,错误可通过编译系统处理。 1. 抛出异常 . Example: float divide(int numer, int div ) { if ( div == 0 ) throw "ERROR: divide by zero. \n"; else return float (numer) / div; }
6.1 异常 (continued) 2. 处理异常。 try { // 可能出现异常的程序代码 } catch( exception param1 ) { // 处理异常类型1的代码 catch( exception param2 ) // 处理异常类型2的代码 // 异常处理结束后,继续执行的代码
// 例6-1 #include <iostream> using namespace std; float divide(int number, int div) { if (div == 0) throw "ERROR: divide by zero.\n"; else return float(number) / div; }
cout << "Enter two numbers: "; cin >> num1 >> num2; void main( ) { int num1, num2; float quotient; cout << "Enter two numbers: "; cin >> num1 >> num2; try { quotient = divide(num1, num2); cout << "The quotient is " << quotient; }catch (char *exceptionString) { cout << exceptionString; } cout << "\nEnd of the program.\n"; 思考:如果不处理又怎么样? 6-1.cpp
6.1 异常 (continued) 异常处理失败的原因: try语句块中实际产生的异常,与catch语句圆括号指定要捕捉的异常类型不匹配; try语句块的范围太小,在try语句之前就已经产生了异常,那么后面的try语句块将不再执行。
6.2 基于对象的异常处理 C++除了支持基本类型的异常处理外,还支持面向对象的异常处理。 6.2 基于对象的异常处理 C++除了支持基本类型的异常处理外,还支持面向对象的异常处理。 C++在处理多种类型的异常时,要求这些异常对象必须属于不同类型,并且对每种类型的异常都要编写一段对应的catch代码。 例如:6-3
{ int input, lower , upper; public: class TooLow{ }; class IntRange { int input, lower , upper; public: class TooLow{ }; class TooHigh{ } ; IntRange( int low, int high ) { lower = low; upper = high; } int getInput( ) { cin >> input; if (input < lower) throw TooLow( ); else if (input > upper) throw TooHigh( ); return input; } }; 新思想:基于对象的异常处理
cout << "输入一个5-10之间的值:" ; try { userValue = range.getInput( ) ; void main( ) { IntRange range( 5 , 10 ) ; int userValue ; cout << "输入一个5-10之间的值:" ; try { userValue = range.getInput( ) ; cout << "你输入的是" << userValue << endl ; }catch( IntRange :: TooLow ) { cout << "输入值小于下限\n" ; }catch( IntRange :: TooHigh ) { cout << "输入值大于上限\n" ; } cout << "程序结束\n" ; 6-3.cpp
6.4 通过异常对象获取异常信息 可以通过异常对象将异常信息传递给异常处理者。 例如:例6-4
class IntRange3 { int input, lower , upper; public: class OutOfRange { public: int value; OutOfRange( int i ){ value = i; } }; IntRange3(int l, int h){ lower=l; upper=h; } int getInput( ) { cin >> input; if (input < lower || input > upper) throw OutOfRange(input); return input; }
cout << "输入一个5-10之间的值:" ; try { userValue = range.getInput( ) ; void main( ) { IntRange3 range( 5 , 10 ) ; int userValue ; cout << "输入一个5-10之间的值:" ; try { userValue = range.getInput( ) ; cout << "你输入的是" << userValue << endl ; } catch( IntRange3 :: OutOfRange ex ) { cout << "输入值" << ex.value << " 越界\n" ; } cout << "程序结束\n" ; 6-4.cpp
注意 一旦程序抛出异常,即使在异常处理以后,程序也不能回到原来的抛出点继续执行,这是因为C++采用的是不可恢复的异常处理模型。 一旦程序抛出异常,执行throw语句的函数将立即停止执行。如果该函数被另外一个函数调用,那么调用者函数也将停止执行,其它依次类推。 如果在try块中创建有对象,并且这些对象还未来得及析构,那么将对这些对象立即调用析构函数。
6.5 再次抛出异常 try{ doSomethingElse( ) ; } catch( exceptionl ) { 6.5 再次抛出异常 try{ doSomethingElse( ) ; } catch( exceptionl ) { throw; // 再次抛出异常,由上层try处理 catch( exception3 ) // 处理exception 3的代码