C++程序设计课程介绍-第15章 异常处理.ppt
第15章 异常处理,写函数库的程序员可以检测到库函数运行时的错误(如数组访问越界),但通常却不知道应该如何处理这些错误异常处理的基本想法是,让一个函数在发现了自己无法处理的错误时抛出一个异常,希望它的(直接或间接)调用者能够处理这个问题。,异常处理,传统错误处理方法异常处理机制抛出异常捕获异常处理异常异常规格说明,传统错误处理方法,可以处理的错误在发生错误的地方就地处理在检查到一个在局部无法处理的问题时,一个函数可以:终止程序 abort()/exit()返回一个表示“错误”的值。int返回一个合法值,让程序处于某种非法的状态。errno调用一个预先准备好在出现“错误”的情况下用的函数。,处理错误的传统方法,处理错误的传统方法:错误处理代码是在整个系统代码中分布的。代码中可能出错的地方都要当场进行错误处理。在写程序时,必须知道所有的错误该如何处理好处:程序员阅读代码时能够直接看到错误处理情况,确定是否实现了正确的错误检查。问题:代码中受到错误处理的“污染”,使应用程序本身的代码更加晦涩难懂,难以看出代码功能是否正确实现。这样就使代码的理解和维护更加困难。,面向对象中的异常处理,面向对象中,程序员经常做的是一些工具(类的设计与实现)这些工具能够检测出错误,但往往不知道该如何处理错误。错误的处理是由工具的使用者决定需要一种机制能将检测到的错误告诉使用者,异常处理,传统错误处理方法异常处理机制抛出异常捕获异常处理异常异常规格说明,异常处理,C+的新异常处理特性:异常处理将检测发现错误的代码与处理错误的代码分开来。程序员的工作也可做相应分工(例如,库函数程序员负责检测异常,而调用库函数的另一程序员则负责捕获与处理异常)。使程序员可以删除程序执行“主线条”中的错误处理代码,从而提高程序的可读性和可维护性。,异常处理基础简介,异常处理代码的一般形式:try可能抛出异常的代码 catch(类型1 参数1)处理该异常的代码catch(类型2 参数2)处理该异常的代码,异常处理,传统错误处理方法异常处理机制抛出异常捕获异常处理异常异常规格说明,抛出异常,如果程序发生异常情况,而在当前的环境中获取不到异常处理的足够信息,我们可以创建一包含出错信息的对象并将该对象抛出当前环境,发送给更大的环境中。这称为异常抛出。例1throw myerror(“something bad happened”);myerror是一个类,它以字符串变量为参数例2 throw int(5)int是一个内部类型,5是一个int类型的常数,throw与其操作数,抛出异常的语句形式:throw;throw通常指定一个操作数(或不指定操作数的特殊情况)。throw的操作数可以是任何类型,如果操作数是个对象,则称为异常对象。也可以抛出条件表达式而不是抛出对象,可以抛出不用于错误处理的对象。抛出异常时,生成和初始化throw操作数的一个临时副本,然后这个临时对象初始化异常处理器中的参数。异常处理器执行完毕和退出时,删除临时对象。,异常抛出实例 异常类定义,/Class DivideByZeroException to be used in exception/handling for throwing an exception on a division by zero.class DivideByZeroException public:DivideByZeroException():message(attempted to divide by zero)const char*what()const return message;private:const char*message;,异常抛出实例 异常抛出,double Div(int x,int y)if(y=0)throw DivideByZeroException();return static_cast(x)/y;,异常处理,传统错误处理方法异常处理机制抛出异常捕获异常处理异常异常规格说明,异常捕获,一个函数抛出异常,它必须假定该异常能被捕获和处理。异常捕获机制使得C+可以把问题集中在一处解决。,catch捕获异常,异常处理器放在catch块中,形式如下:catch()catch处理器定义自己的范围。catch在括号中指定要捕获的对象类型。catch处理器中的参数可以命名也可以无名。如果是命名参数,则可以在处理器中引用这个参数。如果是无名参数(只指定匹配抛出对象类型的类型),则信息不从抛出点传递到处理器中,只是把控制从抛出点转到处理器中许多异常都可以这样。catch()捕获任意类型的异常。,异常捕获原理,如果一个异常信号被抛出,异常处理器中第一个参数与异常抛出对象相匹配的函数将捕获该异常信号,然后进入相应的catch语句,执行异常处理程序。,除零异常的捕获,int main()int number1,number2;double result;cout number1 number2)try result=Div(number1,number2);cout The quotient is:result endl;catch(DivideByZeroException ex)cout Exception occurred:ex.what()n;cout nEnter two integers(end-of-file to end):“;cout endl;return 0;,输出结果,Enter tow integers(end-of-file to end);l00 7The quotient is:14.2857Enter tow integers(end-of-file to end);100 0Exception occurred:attempted to divide by zeroEnter tow integers(end-of-file to end);33 9The quotient is:3.66667Enter tow integers end-of-file to end):,异常抛出与检测实例二,int Div(int x,int y)if(y=0)throw y;return x/y;,抛出的异常不一定是对象,可以是一个结果为内置类型的表达式,int main()try cout Div(6,3)endl;cout Div(10,0)endl;cout Div(5,2)endl;catch(int)cout divide by zero endl;cout Its Over endl;return 0;,2divide by zeroIts Over,异常处理,传统错误处理方法异常处理机制抛出异常捕获异常处理异常异常规格说明,异常规格说明,传统函数声明:void f();函数可以抛出任何异常。void f()throw();函数不会有异常抛出。Void f()throw(toobig,toosmall,divzero);函数会抛出toobig,toosmall,divzero三种异常,#include using namespace std;class up;class down;void f(int i)throw(up,down);int main()for(int i=1;i=3;+i)try f(i);catch(up)cout up catched endl;catch(down)cout down catched endl;return 0;void f(int i)throw(up,down)switch(i)case 1:throw up();case 2:throw down();,up catcheddown catched,小结,为了提高程序的鲁棒性,程序需要对各种可能的异常进行处理某些错误需要异地处理C+的异常机制由try、throw和catch构成,