您好,欢迎访问三七文档
《C++面向对象程序设计》教学内容第1章C++概述第2章类和对象第3章面向对象程序设计概述第4章进一步学习类和对象第5章堆与复制构造函数第6章继承性:派生类第7章运算符重载第8章虚函数和多态性第9章模板第10章类库和C++的标准模板库STL第11章输入输出流第12章异常处理第12章异常处理12.1异常处理的概念12.2C语言处理异常的方法12.3C++语言的异常处理方法12.4异常类和C++标准异常12.1异常处理的概念•异常(Exception)是程序可能检测到的运行时刻不正常的情况。•最常见的异常包括–除数为0,数组越界访问,磁盘或者光盘读写失败,无效数据,内存耗尽,网络不通等。•异常总是代表着某些不该发生的事情发生了异常错误•在程序运行阶段由于系统异常原因而产生的错误称为异常错误•异常错误与程序设计错误是两码事异常错误与程序设计错误•程序设计错误是指程序员在设计程序时由于人为因素所产生的错误。•异常错误是在程序运行时由于系统异常原因而产生的,不是程序员的失误所致。•如果不排除程序设计错误,程序就不能通过编译检查或运行结果不对。•如果不处理异常错误,程序执行时遇到异常情况就会突然终止或失控,使用户感到莫名其妙。一个异常错误的例子#includefstream#includeiostreamusingnamespacestd;intmain(intargc,char**argv){ifstreamsource(argv[1]);//打开文件charline[128];while(!source.eof()){source.getline(line,sizeof(line));coutlineendl;}source.close();return0;}异常处理•异常处理即异常错误处理•异常处理的任务就是使程序的运行过程能从异常错误中恢复过来继续执行•或者通知用户遇到了何种异常,不得不停止执行。•Improvederrorrecoveryisoneofthemostpowerfulwaysyoucanincreasetherobustnessofyourcode.•robustness鍵壯性,穩固性,穩健性,堅固性异常处理的例子intmain(intargc,char**argv){ifstreamsource(argv[1]);//打开文件charline[128];if(source.fail()){couterroropeningthefileargv[1]endl;exit(1);}while(!source.eof()){source.getline(line,sizeof(line));coutlineendl;}source.close();return0;}异常处理代码12.2C语言处理异常的方法12.2.1检查函数的返回值来发现异常错误12.2.2使用signal()和raise()函数12.2.3使用非局部的跳转Goto函数12.2.1检查函数的返回值来发现异常错误•从函数返回出错信息,如果函数的返回值不便于返回出错信息,就设置一个全局的出错标志。(标准C提供errno和perror()来支持这种方法)•这种方法的缺陷:繁琐–处理异常的代码和正常算法的代码交织在一起,增加了代码的复杂性,降低了可读性。–程序员很容易忽视函数的返回值。printf()–设置全局的出错标志降低了各个模块的独立性。12.2.2使用signal()和raise()函数•使用C语言标准库中的信号处理系统中的signal()函数和raise()函数。•这种方法的缺陷:复杂–程序员需要理解信号产生的机制并安装合适的信号处理机制。–对于大型项目,不同库之间的信号可能会产生冲突。12.2.3使用非局部的跳转Goto函数•使用C标准库中非局部的跳转函数:setjmp()和longjmp()。•这种方法的缺陷:–增加了模块之间的耦合性•上述第二和第三种方法的共同缺陷:不能调用析构函数进行善后处理,不能释放对象占用的资源。实际上不可能有效正确地从异常情况中恢复出来。12.3C++语言的异常处理方法•C++的异常处理机制的基本思想是将异常的检测与处理分离。•C++中异常错误处理用try、throw和catch三个关键字实现一个异常处理的简单例子#includeiostreamusingnamespacestd;intmain(){intm,n;coutPleaseinputtwointegers:;cinmn;try{if(n==0)throw0;cout(m/n)endl;}catch(int){coutDividedby0!endl;return-1;}return0;}catch语句捕获一个整型异常并处理在try代码块中包含需要监控的程序部分抛出一个整型异常12.3.1C++程序处理异常的一般形式try{//tryBlock}catch(type1arg){//exceptionhandlingfortype1}catch(type2arg){//exceptionhandlingfortype2}//...catch(typeNarg){//exceptionhandlingfortypeN}try和throw要监控的程序部分必须包含在try代码块中,(在try块中调用的函数也将被监控,参见)。如果try块中的程序代码发生了异常错误,那么这个异常将被抛出(使用throw)。try块中抛出的异常将被紧跟在try语句之后的catch语句捕获。另一个异常处理的简单例子intdivision(intx,inty);intmain(){intm,n;coutPleaseinputtwointegers:;cinmn;try{coutdivision(m,n)endl;}catch(int){coutDividedby0!endl;return-1;}return0;}intdivision(intx,inty){if(y==0)throw0;returnx/y;}返回catch语句捕获一个整型异常并处理在try代码块中包含需要监控的程序部分抛出一个整型异常catch•当在try中的代码抛出一个异常时,它将被相应的catch语句捕获并处理。•在try语句后面可以有一个或多个catch语句。•如果在catch语句中指定的数据类型与异常的类型匹配,那么这个catch语句将被执行。•所有其他的catch语句都将被忽略。catch(续)•当异常信息被捕获时,变量arg将用来接收异常信息的值。例如:•如果抛出的异常没有与之类型相匹配的catch语句,那么将发生非正常的程序终止(abnormalprogramtermination)。例如•如果程序中抛出了一个未被处理的异常,系统将调用C++标准库中的函数terminate()。•在默认情况下,函数terminate()将调用abort()函数来终止程序,但如果需要,也可以定制自己定义的函数来终止程序的执行。变量arg用来接收异常的值#includeiostreamusingnamespacestd;intmain(){intm,n;coutPleaseinputtwointegers:;cinmn;try{if(n==0)throwDividedby0!;cout(m/n)endl;}catch(char*arg){coutargendl;return-1;}return0;}返回变量arg用来接收throw抛出的异常值抛出的异常的值与变量arg类型不配#includeiostreamusingnamespacestd;intmain(){intm,n;coutPleaseinputtwointegers:;cinmn;try{if(n==0)throw0;cout(m/n)endl;}catch(char*arg){coutargendl;return-1;}return0;}返回抛出的异常的值与变量arg类型不配12.3.2捕获函数内部抛出的异常#includeiostreamusingnamespacestd;intdivision(intx,inty);intmain(){intm,n;coutPleaseinputtwointegers:;cinmn;try{coutdivision(m,n)endl;}catch(int){coutDividedby0!endl;return-1;}return0;}从函数内部抛出异常intdivision(intx,inty){if(y==0)throw0;//异常信息从函数内部抛出returnx/y;}12.3.3多个catch语句voidXhandler(inttest){try{if(test)throwtest;elsethrowValueiszero;}catch(inti){coutCaughtOne!Ex.#:i'\n';}catch(char*str){coutCaughtastring:;coutstr'\n';}}每个catch语句所能捕获的异常必须是不同类型使用多个catch语句(续)intmain(){coutstart\n;Xhandler(1);Xhandler(2);Xhandler(0);Xhandler(3);coutend;return0;}12.3.4非正常的程序终止#includeiostreamusingnamespacestd;intmain(){intm,n;coutPleaseinputtwointegers:;cinmn;try{if(n==0)throw0;cout(m/n)endl;}catch(char*arg)//抛出的异常信息的值与形参变量arg类型不配{coutargendl;return-1;}return0;}abnormalprogramtermination•执行上面的程序时,如果输入的除数为零,就会发生程序非正常终止。•执行情况如下:Pleaseinputtwointegers:20abnormalprogramtermination非正常的程序终止•如果抛出的异常没有与之类型相匹配的catch语句,则该异常信息将被传递到调用该程序模块的上一级,它的上级捕获到这个异常信息后进行处理。•如果上一级模块仍然不能处理,就再传递给其上一级,如此逐级上传,如果到最高一级还无法处理。那么将发生非正常的程序终止(abnormalprogramtermination)。12.3.5自定义运行终止函数•如果在程序中抛出了一个未被处理的异常信息,系统将调用C++标准库中的函数terminate()。在默认情况下,函数terminate()将调用abort()函数来终止程序。•程序员也可以编写自己的终止函数,然后通过set_terminate函数传递给异常处理模块,使系统在找不到相匹配的异常错误处理模块时调用该函数。示例:自定义的运行终止函数#includeiostreamusingnamespacestd;voidmyterm()//自定义的运行终止函数{coutThisismyterminater.endl;//...释放程序中申请的系统资源exit(1);}intmain(){//...try{set_terminate(myterm);//...throwException...;}catch(inti){}return0;}12.3.6捕获所有的异常voidXhandler(inttest){try{if(test==0)throwtest;//throwintif(test==1)throw'a';//throwcharif(t
本文标题:第12章 异常处理
链接地址:https://www.777doc.com/doc-3169248 .html