第11章异常处理_第1页
第11章异常处理_第2页
第11章异常处理_第3页
第11章异常处理_第4页
第11章异常处理_第5页
已阅读5页,还剩37页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第11章章 异常处理异常处理n11.1 异常处理概述异常处理概述n11.2 异常处理的基本思想异常处理的基本思想n11.3 异常处理的实现异常处理的实现n11.4 标准标准C+库中的异常类库中的异常类n11.5 多路捕获多路捕获n11.6 含有异常的程序设计含有异常的程序设计11.1 异常处理概述异常处理概述n程序可能按编程者的意愿终止,也可能因为程序中发生程序可能按编程者的意愿终止,也可能因为程序中发生了错误而终止。了错误而终止。n程序的错误有两种,一种是编译错误,即语法错误。如程序的错误有两种,一种是编译错误,即语法错误。如果使用了错误的语法、函数、结构和类,程序就无法被果使用了错误的语

2、法、函数、结构和类,程序就无法被生成运行代码。另一种是在运行时发生的错误,它分为生成运行代码。另一种是在运行时发生的错误,它分为不可预料的逻辑错误和可以预料的运行异常。不可预料的逻辑错误和可以预料的运行异常。n异常处理机制是用于管理程序运行期间错误的一种结构异常处理机制是用于管理程序运行期间错误的一种结构化方法。所谓结构化是指程序的控制不会由于产生异常化方法。所谓结构化是指程序的控制不会由于产生异常而随意跳转。异常处理机制将程序中的正常处理代码与而随意跳转。异常处理机制将程序中的正常处理代码与异常处理代码显式区别开来,提高了程序的可读性。异常处理代码显式区别开来,提高了程序的可读性。 返回首页

3、11.2 异常处理的基本思想异常处理的基本思想n异常的基本思想是:异常的基本思想是: n(1)实际的资源分配通常在程序的低层进行,如上图)实际的资源分配通常在程序的低层进行,如上图中的中的F3()。n(2)当操作失败、无法分配内存或无法打开一个文件当操作失败、无法分配内存或无法打开一个文件时,在逻辑上如何进行处理通常在程序的高层,如上图时,在逻辑上如何进行处理通常在程序的高层,如上图中的中的F1(),中间还可能有与用户的对话。中间还可能有与用户的对话。n(3)异常为从分配资源的代码转向处理错误状态的代)异常为从分配资源的代码转向处理错误状态的代码提供了一种表达方式。如果还存在中间层次的函数,码

4、提供了一种表达方式。如果还存在中间层次的函数,如上图中的如上图中的F2(),则为它们释放所分配的内存提供了机则为它们释放所分配的内存提供了机会,但这并不包括传递错误状态信息的代码。会,但这并不包括传递错误状态信息的代码。返回首页图11-1 异常处理示意图返回本节11.3 异常处理的实现异常处理的实现n11.3.1 异常处理的语法异常处理的语法n11.3.2 异常处理机制异常处理机制返回首页nC+语言异常处理机制的基本思想是将异常的检语言异常处理机制的基本思想是将异常的检测与处理分离。当在一个函数体中检测到异常测与处理分离。当在一个函数体中检测到异常条件存在,但无法确定相应的处理方法时,将条件存

5、在,但无法确定相应的处理方法时,将引发一个异常,并由函数的直接或间接调用检引发一个异常,并由函数的直接或间接调用检测并处理这个异常。这一基本思想用测并处理这个异常。这一基本思想用3个保留字个保留字实现:实现:throw、try和和catch。其作用是:其作用是:n(1)try:标识程序中异常语句块的开始。标识程序中异常语句块的开始。n(2)throw:用来创建用户自定义类型的异常用来创建用户自定义类型的异常错误。错误。n(3)catch:标识异常错误处理模块的开始。标识异常错误处理模块的开始。 11.3.1 异常处理的语法异常处理的语法n在在C+程序中,任何需要检测异常的语句(包括程序中,任何

6、需要检测异常的语句(包括函数调用)都必须在函数调用)都必须在try语句块中执行,异常必语句块中执行,异常必须由紧跟在须由紧跟在try语句后面的语句后面的catch语句来捕获并处语句来捕获并处理。因而,理。因而,try与与catch总是结合使用。总是结合使用。throw、try和和catch语句的一般语法如下:语句的一般语法如下: throw ;try/try语句块语句块catch(类型类型1 参数参数1)/针对类型针对类型1的异常处理的异常处理catch (类型类型2 参数参数2)/针对类型针对类型2的异常处理的异常处理catch (类型类型n 参数参数n)/针对类型针对类型n的异常处理的异常

7、处理ntry子句后的复合语句是代码的保护段。如果预子句后的复合语句是代码的保护段。如果预料某段程序代码(或对某个函数的调用)有可料某段程序代码(或对某个函数的调用)有可能发生异常,就将它放在能发生异常,就将它放在try子句之后。如果这子句之后。如果这段代码(或被调函数)运行时真的遇到异常情段代码(或被调函数)运行时真的遇到异常情况,其中的况,其中的throw表达式就会抛掷这个异常。表达式就会抛掷这个异常。ncatch子句后的复合语句是异常处理程序,子句后的复合语句是异常处理程序,“捕捕获获”(处理)由(处理)由throw表达式抛掷的异常。异常表达式抛掷的异常。异常类型说明部分指明该子句处理的异

8、常的类型,类型说明部分指明该子句处理的异常的类型,它与函数的形参是类似的,可以是某个类型的它与函数的形参是类似的,可以是某个类型的值,也可以是引用。值,也可以是引用。 n例例11-1:异常处理示例程序。异常处理示例程序。 #includevoid main() char* ptr; try /异常模块异常模块 if(ptr=new char64*1024)=NULL) throw Not Enough Memory!; catch(char* str) /异常错误处理模块异常错误处理模块 / 错误处理代码错误处理代码 coutException:strendl; n异常处理的执行过程如下:异常

9、处理的执行过程如下: (1)控制通过正常的顺序执行到达)控制通过正常的顺序执行到达try语句,然后语句,然后执行执行try块内的保护段。块内的保护段。(2)如果在保护段执行期间没有引起异常,那么)如果在保护段执行期间没有引起异常,那么跟在跟在try块后的块后的catch子句就不执行,程序从异常子句就不执行,程序从异常被抛掷的被抛掷的try块后跟随的最后一个块后跟随的最后一个catch子句后面子句后面的语句继续执行下去。的语句继续执行下去。(3)如果在保护段执行期间或在保护段调用的任)如果在保护段执行期间或在保护段调用的任何函数中(直接或间接的调用)有异常被抛掷,何函数中(直接或间接的调用)有异

10、常被抛掷,则从通过则从通过throw运算数创建的对象中创建一个异运算数创建的对象中创建一个异常对象(这隐含指可能包含一个拷贝构造函常对象(这隐含指可能包含一个拷贝构造函数)。数)。 n( 4) 如 果 匹 配 的 处 理 器 未 找 到 , 则 函 数) 如 果 匹 配 的 处 理 器 未 找 到 , 则 函 数terminate将被自动调用,而函数将被自动调用,而函数terminate的的默认功能是调用默认功能是调用abort终止程序。终止程序。n(5)如果找到了一个匹配的)如果找到了一个匹配的catch处理程序,处理程序,且它通过值进行捕获,则其形参通过拷贝异常且它通过值进行捕获,则其形参

11、通过拷贝异常对象进行初始化。对象进行初始化。 n例例11-2:阅读下列程序,写出运行结果。阅读下列程序,写出运行结果。 #includevoid Excp();class Expublic:Ex();Ex();class Demopublic:Demo()/构造函数构造函数 coutCreateing a Demo object.endl; Demo()/析构函数析构函数 c o u t D e l e t i n g D e m o object.endl;void Excp()Demo A;/定义一个对象定义一个对象coutExcp function throwing an excepti

12、on!;coutendl;throw Ex();/创建成一个异常创建成一个异常void main()try coutNow call Excp function.endl; Excp(); catch(Ex a)/捕捉捕捉Ex类异常类异常 coutAn Ex exception occurred.endl; catch(.)coutSome other exception occurred.;coutendl;此程序的运行结果为:此程序的运行结果为:Now call Excp function.Creating a Demo object.Excp function throwing an e

13、xception!Deleting Demo object.An Ex exception occurred.返回本节11.3.2 异常处理机制异常处理机制n(1)try分程序必须出现在前,分程序必须出现在前,catch紧跟出现在后。紧跟出现在后。catch之后的圆括号中必须含有数据类型,捕获是利用之后的圆括号中必须含有数据类型,捕获是利用数据类型匹配实现的。数据类型匹配实现的。n(2)如果程序内有多个异常错误处理模块,则当异常)如果程序内有多个异常错误处理模块,则当异常错误发生时,系统自动查找与该异常错误类型相匹配的错误发生时,系统自动查找与该异常错误类型相匹配的catch模块,查找次序为模

14、块,查找次序为catch出现的次序。出现的次序。n(3)如果异常错误类型为)如果异常错误类型为C+的类,并且该类有其基的类,并且该类有其基类,则应该将派生类的错误处理程序放在前面,基类的类,则应该将派生类的错误处理程序放在前面,基类的错误处理程序放在后面。错误处理程序放在后面。n(4)如果一个异常错误发生后,系统找不到一个与该)如果一个异常错误发生后,系统找不到一个与该错误类型相匹配的异常错误处理模块,则调用预定义的错误类型相匹配的异常错误处理模块,则调用预定义的运行时刻终止函数,默认情况下是运行时刻终止函数,默认情况下是abort。n例例11-3:定义一个异常类定义一个异常类CExcepti

15、on,有成员函数有成员函数Reason()用来显示异常用来显示异常的类型,定义函数的类型,定义函数fun()触发异常,在主函数的触发异常,在主函数的try模块中调用模块中调用fun(),在在catch模块中捕获异常,观察程序的执行过程。模块中捕获异常,观察程序的执行过程。#include class CExceptionpublic:CException()CException()const char *Reason() const return CException 类中的异类中的异常。常。; ; void fun()cout在子函数中触发在子函数中触发CException类异常类异常end

16、l;throw CException(); void main()cout进入主函数进入主函数endl;trycout在在try模块中,调用子函数模块中,调用子函数endl;fun();catch(CException E)cout在在catch模块中,捕获到模块中,捕获到CException类型异常:类型异常:;coutE.Reason()endl;catch(char *str)cout捕获到其他类型异常:捕获到其他类型异常:strendl;cout回到主函数,异常已被处理。回到主函数,异常已被处理。endl; 程序的运行结果为:程序的运行结果为:进入主函数进入主函数在在try模块中,调用

17、子函数模块中,调用子函数在子函数中触发在子函数中触发CException类异常类异常在在catch模块中,捕获到模块中,捕获到CException类型异常:类型异常:CException 类中的异常。类中的异常。回到主函数,异常已被处理。回到主函数,异常已被处理。n例例11-4:设计一个异常设计一个异常Exception抽象类,在此基础上派生一个抽象类,在此基础上派生一个OutOfMemory类响应内存不足,一个类响应内存不足,一个RangeError类响应输入的数不在指类响应输入的数不在指定的范围内,实现并测试这几个类。定的范围内,实现并测试这几个类。#include class Excep

18、tionpublic:Exception()virtual Exception()virtual void PrintError()=0; class OutOfMemory:public Exceptionpublic:OutOfMemory()OutOfMemory()virtual void PrintError(); void OutOfMemory:PrintError()coutOut of Memory!endl; class RangeError:public Exceptionpublic:RangeError(unsigned long number)BadNum=numb

19、er;RangeError()virtual void PrintError();virtual unsigned long GetNumber()return BadNum;v i r t u a l v o i d S e t N u m b e r ( u n s i g n e d l o n g number)BadNum=number;private:unsigned long BadNum; void RangeError:PrintError()c o u t N u m b e r o u t o f r a n g e . Y o u u s e d GetNumber()

20、!endl; void fun1();unsigned int *fun2();void fun3(unsigned int *);int main()tryfun1(); catch(Exception& theException)theException.PrintError();return 0; void fun1()unsigned int *p=fun2();fun3(p);coutThe number is:*pendl;delete p;unsigned int *fun2()unsigned int *n=new unsigned int;if(n=0)throw O

21、utOfMemory();return n; void fun3(unsigned int *p)long Number;coutNumber;if(Number999|Number0)throw RangeError(Number);*p=Number;程序运行结果为:程序运行结果为:Enter an integer(0999):7 The number is:7Enter an integer(0999):2004 Number out of range.You used 2004!n例例11-5:编写用户自定义的终止函数。编写用户自定义的终止函数。#include #include #i

22、nclude void myterm()coutThis is my terminater.endl; /其他代码其他代码 exit(-1); ;int main() /其他代码其他代码 tryset_terminate(myterm);/传递终止函数传递终止函数名名 /其他代码其他代码throw Exception:.; catch(int i) /其他代码其他代码 return 0;返回本节11.4 标准标准C+库中的异常类库中的异常类n标准标准C+库中包含库中包含9个异常类,它们可以分为运行时异常和逻辑异个异常类,它们可以分为运行时异常和逻辑异常:常: length_error /运行时

23、长度异常运行时长度异常domain_error /运行时域异常运行时域异常out_of_range_error /运行时越界异常运行时越界异常invalid_argument/运行时参数异常运行时参数异常range_error/逻辑异常,范围异常逻辑异常,范围异常overflow_error/逻辑异常,溢出(上)异常逻辑异常,溢出(上)异常underflow_error/逻辑异常,溢出(下)异常逻辑异常,溢出(下)异常返回首页n下面程序简单说明下面程序简单说明C+异常标准类异常标准类exception和和logic_error的使用的使用方法。方法。n例例11-6:演示标准异常类的使用。演示标

24、准异常类的使用。#include #include using namespace std;void maintry exception theError;/声明一个声明一个C+标准标准异常类的对象异常类的对象throw(theError);/抛出该异常类的对象抛出该异常类的对象catch(const exception &theError)/捕捉捕捉C+标准异常类的对象标准异常类的对象 couttheError.what()endl;trylogic_error theLogicError(“Logic Error!”);/声明一个声明一个C+标准异常类(标准异常类(logic_er

25、ror)的对象的对象throw(theLogicError); /抛出该异常类对象抛出该异常类对象catch(const exception &theLogicError)/捕捉捕捉C+标准异常类的对象标准异常类的对象 couttheLogicError.what()endl;/用用what成员函数显示出错的成员函数显示出错的原因原因返回本节11.5 多路捕获多路捕获n很多程序可能有若干不同种类的运行错误,它们可以使很多程序可能有若干不同种类的运行错误,它们可以使用异常处理机制,每种错误可与一个类,一种数据类型用异常处理机制,每种错误可与一个类,一种数据类型或一个值相关。这样,在程序中

26、就会出现多路捕获。或一个值相关。这样,在程序中就会出现多路捕获。n例例11-7:操作操作string类对象时,预设两个异常。类对象时,预设两个异常。#include #include class Stringpublic: String(char *,int)class yichang1 /异常类异常类1返回首页public: yichang1(int j):index(j) int index;class yichang2 ; /异常类异常类2char& operator(int k)if(k=0 & klen) return pk; throw yichang1(k);pr

27、ivate: char *p; int len;static int max;int String:max=20;String:String(char *str,int si) if(simax) throw yichang2();p=new charsi;strncpy(p,str,si);len=si;void g(String& str)int num=10;for(int n=0;nnum;n+) coutstrn;coutendl;void f()/代码区代码区1try /代码区代码区2String s(abcdefghijklmnop,10);g(s);catch(String:yichang1 r)cerrout of range:r.indexendl;/代码区代码区3catch(String:yichang2)cerrsize illegal!n;coutThe program will be continued here.nn;/代码区代码区4void main()/代码区代码区5f();coutThese code is not effected by p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论