C++大学基础教程第十三章异常处理_第1页
C++大学基础教程第十三章异常处理_第2页
C++大学基础教程第十三章异常处理_第3页
C++大学基础教程第十三章异常处理_第4页
C++大学基础教程第十三章异常处理_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

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

文档简介

2020 4 17 1 C 大学基础教程 第13章异常处理北京邮电大学电信工程学院计算机技术中心 程序设计的要求之一就是程序的健壮性 希望程序在运行时能够不出或者少出问题 但是 在程序的实际运行时 总会有一些因素会导致程序不能正常运行 异常处理 ExceptionHandling 就是要提出或者是研究一种机制 能够较好的处理程序不能正常运行的问题 第十三章异常处理 13 1异常和异常处理13 2C 异常处理机制13 3用类的对象传递异常13 4异常处理中的退栈和对象析构 13 1异常和异常处理 2020 4 17 北京邮电大学电信工程学院计算机技术中心 5 13 1 1异常及其特点 异常 Exceptions 是程序在运行时可能出现的会导致程序运行终止的错误 编译系统检查出来的语法错误 导致程序运行结果不正确的逻辑错误 都不属于异常的范围 异常是一个可以正确运行的程序在运行中可能发生的错误 2020 4 17 北京邮电大学电信工程学院计算机技术中心 6 13 1 1异常及其特点 常见的异常 如 系统资源不足 如内存不足 不可以动态申请内存空间 磁盘空间不足 不能打开新的输出文件 等 用户操作错误导致运算关系不正确 如出现分母为0 数学运算溢出 数组越界 参数类型不能转换 等 2020 4 17 北京邮电大学电信工程学院计算机技术中心 7 13 1 1异常及其特点 异常有以下的一些特点 偶然性 程序运行中 异常并不总是会发生的 可预见性 异常的存在和出现是可以预见的 严重性 一旦异常发生 程序可能终止 或者运行的结果不可预知 2020 4 17 北京邮电大学电信工程学院计算机技术中心 8 13 1 2异常处理方法及举例 对于程序中的异常 通常有三种处理的方法 不作处理 很多程序实际上就是不处理异常的 发布相应的错误信息 然后 终止程序的运行 在C语言的程序中 往往就是这样处理的 适当的处理异常 一般应该使程序可以继续运行 2020 4 17 北京邮电大学电信工程学院计算机技术中心 9 13 1 2异常处理方法及举例 一般来说 异常处理 ExceptionHandling 就是在程序运行时对异常进行检测和控制 而在C 中 异常处理 EH 就是用C 提供的try throw catch的模式进行异常处理的机制 2020 4 17 北京邮电大学电信工程学院计算机技术中心 10 例13 1程序将连续地输入两个实数 通过调用函数 返回这两个数相除的商 并且要注意除数不能为0 例13 1用一般的方法处理除法溢出 include includedoubledivide doublea doubleb if b 0 检测分母是不是为0 cout 除数不可以等于0 endl abort 调用abort函数终止运行 returna b 2020 4 17 北京邮电大学电信工程学院计算机技术中心 11 voidmain doublex y z cout x y z divide x y cout cout Bye n 2020 4 17 北京邮电大学电信工程学院计算机技术中心 12 如果出现分母为0的情况 运行将出现以下结果 2020 4 17 北京邮电大学电信工程学院计算机技术中心 13 13 1 2异常处理方法及举例 这个程序中 对于除数为0的处理有这样的特点 异常的检测和处理都是在一个程序模块 divide函数 中进行的 由于函数的返回值是double型的数据 因此 即使检测到除数为0的情况 也不能通过返回值来反映这个异常 只能调用函数abort终止程序的运行 13 2C 异常处理机制 2020 4 17 北京邮电大学电信工程学院计算机技术中心 15 13 2C 异常处理机制 C 处理异常有两个基本的做法 异常的检测和处理是在不同的代码段中进行的 一般的说法是在 try 部分检测异常 catch 部分处理异常 由于异常的检测和处理不是在同一个代码段中进行的 在检测异常和处理异常的代码段之间需要有一种传递异常信息的机制 在C 中是通过 对象 来传递异常的 这种对象可以是一种简单的数据 如整数 也可以是系统定义或用户自定义的类的对象 2020 4 17 北京邮电大学电信工程学院计算机技术中心 16 13 2C 异常处理机制 C 异常处理的语法可以表述如下 try 受保护语句 throw异常 其他语句 catch 异常类型 异常处理语句 检测和抛掷异常 扑获和处理异常 try模块 2020 4 17 北京邮电大学电信工程学院计算机技术中心 17 13 2C 异常处理机制 在C 术语中 异常 Exception 注意结尾没有s 是作为专用名词出现的 就是将异常检测程序所抛掷的 带有异常信息的对象 称为 异常 而将捕获异常的处理程序称为异常处理程序 ExceptionHandler 2020 4 17 北京邮电大学电信工程学院计算机技术中心 18 13 2C 异常处理机制 在try复合语句中 可以调用其他函数 在所调用的函数中检测和抛掷异常 而不是在try复合语句中直接抛掷异常 这个所调用的函数 仍然是属于这个try模块的 所以这个模块中的catch部分 仍然可以捕获它所抛掷的异常并进行处理 2020 4 17 北京邮电大学电信工程学院计算机技术中心 19 例13 2用C 的异常处理机制 重新处理例13 1 例13 2用C 的异常处理机制 处理除法溢出 include includedoubledivide doublea doubleb if b 0 throw 输入错误 除数不可以等于0 returna b 2020 4 17 北京邮电大学电信工程学院计算机技术中心 20 voidmain doublex y z cout x y try z divide x y catch constchar s startofexceptionhandler cout cout 程序结束 再见 n 2020 4 17 北京邮电大学电信工程学院计算机技术中心 21 13 2C 异常处理机制 程序运行的一种结果是 输入两个实数x和y 1 23 2x除以y等于0 375输入下一组数 3 40输入错误 除数不可以等于0 输入一对新的实数 2 34 5x除以y等于0 511111输入下一组数 q程序结束 再见 2020 4 17 北京邮电大学电信工程学院计算机技术中心 22 13 2C 异常处理机制 阅读这个程序 可以注意以下几点 在try的复合语句中 调用了函数divide 因此 尽管divide函数是在try模块的外面定义的 它仍然是属于try模块 在try语句块中运行 divide函数检测到异常后 抛掷出一个字符串作为异常对象 异常的类型就是字符串类型 catch程序块指定的异常对象类型是char 可以捕获字符串异常 捕获异常后的处理方式是通过continue语句 跳过本次循环 也不输出结果 直接进入下一次循环 要求用户再输入一对实数 2020 4 17 北京邮电大学电信工程学院计算机技术中心 23 13 2C 异常处理机制 例13 2的执行过程可以简要的表示如下 2020 4 17 北京邮电大学电信工程学院计算机技术中心 24 13 2C 异常处理机制 另外 在编写带有异常处理的程序时 还要注意 try语句块和catch语句块是一个整体 两者之间不能有其他的语句 一个try语句块后面可以有多个catch语句 但是 不可以几个try语句块后面用一个catch语句 13 3用类的对象传递异常 2020 4 17 北京邮电大学电信工程学院计算机技术中心 26 13 3用类的对象传递异常 throw语句所传递的异常 可以是各种类型的 整型 实型 字符型 指针 等等 也可以用类对象来传递异常 对象就是既有数据属性 也有行为属性 使用对象来传递异常 就是既可以传递和异常有关的数据属性 也可以传递和处理异常有关的行为或者方法 专门用来传递异常的类称为异常类 异常类可以是用户自定义的 也可以是系统提供的exception类 2020 4 17 北京邮电大学电信工程学院计算机技术中心 27 13 3 1用户自定义类的对象传递异常 我们用第十章中的栈类模板来作为例子 类模板中两个主要的函数push和pop的定义中 都安排了错误检查的语句 以检查栈空或者栈满的错误 由于pop函数是有返回值的 在栈空的条件下 是没有数据可以出栈的 尽管pop函数可以检测到这种错误 但是 也不可能正常的返回 于是只好通过exit函数调用结束程序的执行 2020 4 17 北京邮电大学电信工程学院计算机技术中心 28 13 3 1用户自定义类的对象传递异常 现在 我们用C 异常处理的机制 改写这个程序 要求改写后的程序不仅有更好的可读性 而且在栈空不能出栈时 程序也可以继续运行 使得程序有更好的健壮性 可以定义两个异常类 一个是 栈空异常 类 另一个是 栈满异常 类 在try块中 如果检测到 栈空异常 就throw一个 StackEmptyException 类的对象 如果检测到 栈满异常 就throw一个 StackOverflowException 类的对象 2020 4 17 北京邮电大学电信工程学院计算机技术中心 29 13 3 1用户自定义类的对象传递异常 例13 3通过对象传递异常 用C 异常处理机制来处理栈操作中的 栈空异常 和 栈满异常 定义两个相应的异常类 通过异常类对象来传递检测到的异常 并且对异常进行处理 要求在栈空的时候用pop函数出栈失败时 程序的运行也不终止 2020 4 17 北京邮电大学电信工程学院计算机技术中心 30 例13 3 带有异常处理的栈 includeusingnamespacestd classStackOverflowException 栈满异常类 public StackOverflowException StackOverflowException voidgetMessage cout 异常 栈满不能入栈 endl classStackEmptyException 栈空异常类 public StackEmptyException StackEmptyException voidgetMessage cout 异常 栈空不能出栈 endl 2020 4 17 北京邮电大学电信工程学院计算机技术中心 31 template 类模板定义classMyStack TStackBuffer i intsize inttop public MyStack void size i top i voidpush constTitem Tpop void 2020 4 17 北京邮电大学电信工程学院计算机技术中心 32 template push成员函数定义voidMyStack push constTitem if top 0 StackBuffer top item elsethrowStackOverflowException 抛掷对象异常return 2020 4 17 北京邮电大学电信工程学院计算机技术中心 33 template pop成员函数定义TMyStack pop void if top i returnStackBuffer top elsethrowStackEmptyException 抛掷另一个对象异常 2020 4 17 北京邮电大学电信工程学院计算机技术中心 34 voidmain 带有异常处理的类模板测试程序 MyStackss for inti 0 i 10 i try if i 3 cout ss pop endl elsess push i catch StackOverflowException 程序执行的结果是 0异常 栈空不能出栈 3异常 栈空不能出栈 6异常 栈空不能出栈 Bye 2020 4 17 北京邮电大学电信工程学院计算机技术中心 35 13 3 1用户自定义类的对象传递异常 这个例子和例13 2有一些明显不同的地方 通过对象传递参数 具体来说 是在throw语句中直接调用异常类的构造函数 生成一个无名对象 如 throwStackEmptyException 来传递异常的 在catch语句中规定的异常类型则是异常类对象的引用 当然 也可以直接用异常类对象作为异常 2020 4 17 北京邮电大学电信工程学院计算机技术中心 36 13 3 1用户自定义类的对象传递异常 通过异常类对象的引用 直接调用异常类的成员函数getMessage 来处理异常 在try语句块后面直接有两个catch语句来捕获异常 也就是说 要处理的异常增加时 catch语句的数目也要增加 运行结果表明 10次循环都已经完成 没有出现因为空栈时不能出栈而退出运行的情况 2020 4 17 北京邮电大学电信工程学院计算机技术中心 37 13 3 2用exception类对象传递异常 C 提供了一个专门用于传递异常的类 exception类 可以通过exception类的对象来传递异常 classexception public exception 默认构造函数exception char 字符串作参数的构造函数exception constexception 2020 4 17 北京邮电大学电信工程学院计算机技术中心 38 13 3 2用exception类对象传递异常 其中和传递异常最直接有关的函数有两个 带参数的构造函数 参数是字符串 一般就是检测到异常后要显示的异常信息 what 函数 返回值就是构造exception类对象时所输入的字符串 可以直接用插入运算符 在显示器上显示 2020 4 17 北京邮电大学电信工程学院计算机技术中心 39 13 3 2用exception类对象传递异常 如果捕获到exception类对象后 只要显示关于异常的信息 则可以直接使用exception类 如果除了错误信息外 还需要显示其他信息 或者作其他的操作 则可以定义一个exception类的派生类 在派生类中可以定义虚函数what的重载函数 以便增加新的信息的显示 2020 4 17 北京邮电大学电信工程学院计算机技术中心 40 13 3 2用exception类对象传递异常 例13 4定义一个简单的数组类 在数组类中重载 运算符 目的是对于数组元素的下标进行检测 如果发现数组元素下标越界 就抛掷一个对象来传递异常 并且要求处理异常时可以显示越界的下标值 2020 4 17 北京邮电大学电信工程学院计算机技术中心 41 13 3 2用exception类对象传递异常 我们使用exception类的对象来传递对象 但是 直接使用exception类对象还是不能满足例题的要求 因为不能传递越界的下标值 为此 可以定义一个exception类的派生类ArrayOverflow 其中包含一个数据成员k 在构造ArrayOverflow类对象时 用越界的下标值初始化这个数据k 在catch块中捕获到这个对象后 可以设法显示对象的k值 2020 4 17 北京邮电大学电信工程学院计算机技术中心 42 例13 4用exception类参与处理异常 include includeusingnamespacestd classArrayOverflow publicexception exception类的派生类 public ArrayOverflow ArrayOverflow inti exception 数组越界异常 n k i constchar what 重新定义的what 函数 cout 数组下标 k 越界 n returnexception what private intk 派生类ArrayOverfow定义结束 2020 4 17 北京邮电大学电信工程学院计算机技术中心 43 classMyArray 数组类的定义 int p 数组首地址intsz 数组大小public MyArray ints p newint s sz s 构造函数 MyArray delete p intsize returnsz int 2020 4 17 北京邮电大学电信工程学院计算机技术中心 44 voidf MyArray for循环结束 程序运行后输出 0数组下标20越界数组越界异常 2 13 4异常处理中的退栈和对象析构 2020 4 17 北京邮电大学电信工程学院计算机技术中心 46 13 4异常处理中的退栈和对象析构 在函数调用时 函数中定义的自动变量将在堆栈中存放 结束函数调用时 这些自动变量就会从堆栈中弹出 不再占用堆栈的空间 这个过程有时被称为 退栈 Stackunwinding 其他的结束动作还包括调用析构函数 释放函数中定义的对象 2020 4 17 北京邮电大学电信工程学院计算机技术中心 47 13 4异常处理中的退栈和对象析构 但是 如果函数执行时出现异常 并且只是采用简单的显示异常信息 然后退出 exit 程序的做法 则程序的执行就会突然中断 结束函数调用时必须完成的退栈和对象释放的操作也不会进行 这样的结果是很不希望的 2020 4 17 北京邮电大学电信工程学院计算机技术中心 48 floatfunction3 intk function3中可能有异常 if k 0 cout function3中发生异常 n 显示异常信息exit 1 退出执行elsereturn123 k voidfunction2 intn ForTestA12 function3 n 第三次调用 voidfunction1 intm ForTestA11 function2 m 第二次调用 voidmain function1 0 第一次调用 2020 4 17 北京邮电大学电信工程学院计算机技术中心 49 13 4异常处理中的退栈和对象析构 程序运行后显示 function3中发生异常在function1和fuction2中分别定义了ForTest类的对象 如果函数可以正常退出 这些对象将被释放 但是 程序运行后只显示了异常信息 没有析构函数被调用的迹象 说明所创建的对象没有被释放 如果采用C 的异常处理机制来进行处理 情况就会完全不同 2020 4 17 北京邮电大学电信工程学院计算机技术中心 50 13 4异常处理中的退栈和对象析构 如果在function3中用throw语句来抛掷异常 就会开始function3的退栈 然后 返回到函数function2开始function2的退栈 并且调用ForTest类析构函数 释放对象A12 接着 返回到函数function1开始functi

温馨提示

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

评论

0/150

提交评论