C程序设计第5章.pptx
《C程序设计第5章.pptx》由会员分享,可在线阅读,更多相关《C程序设计第5章.pptx(56页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、2023/4/1315.1 异常的概念5.1.1异常的概念程序运行过程中,由于环境变化、用户操作失误以及其它方面的原因而产生的运行时不正常的情况,它要求程序立即进行处理,否则将会引起程序错误甚至崩溃的现象。常见的异常有:空闲内存耗尽、请求打开不存在的文件、被0除、打印机未打开、数组越界访问等。第1页/共56页2023/4/1325.1.2 异常的产生C+程序是由一些相互分离的模块组成的,程序中出现错误和解决出现的错误就会分成两个部分:(1)某个模块A出现错误,但它并没有能力在模块A内解决这个错误,因此它就给出关于这个错误的报告。(2)某个模块B能够检测到模块A发出的错误报告,并处理这个错误,使
2、出现错误造成的损失减到最小。第2页/共56页2023/4/1335.2 异常处理机制 5.2.1基本概念1抛出异常如果程序发生异常情况,而在当前的上下文环境中获取不到处理这个异常的足够信息,程序将创建一个包含出错信息的对象并将该对象抛出当前上下文环境,将错误信息发送到更大的上下文环境中,这个过程称为抛出(throw)异常。第3页/共56页2023/4/1345.2.1 基本概念2捕捉异常对于一个抛出的异常,如果某一个模块能够(或想要)处理这个异常,它就可以获得程序的控制权处理该异常,这个过程称为捕捉(catch)异常。3处理异常当某个catch块捕捉到异常后,它就根据事先制定的策略对异常进行处
3、理,这就是处理异常。在C+中,只有catch块能够捕获异常并进行处理,因此catch块又称为异常处理器。第4页/共56页2023/4/1355.2.1 基本概念4C+的异常处理机制C+的异常处理机制就是将抛出异常与捕捉异常、处理异常分离开来。抛出异常的模块并不负责异常的处理,它只是报告某个地方存在错误,这个报告可以帮助异常处理器解决这个错误。而异常处理器则根据抛出异常模块的报告来处理异常,如果没有模块抛出异常,就不会有异常的处理。第5页/共56页2023/4/1365.2.2 throw语句抛出异常的语法格式如下:throw表达式这里,throw后的表达式表示异常的类型,它可以是一个变量或一个
4、对象。throw语句在语法上与return语句相似。下面是两条throw语句的例子。throw1;throw(“出现异常”);异常抛出后,程序的控制权就从异常抛出的地方交出,由编译器寻找匹配的异常处理器进行相应的处理。第6页/共56页2023/4/1375.2.3 try块 try块的语法格式如下:try复合语句try块必须包围能够抛出异常的语句。它提示编译器到那里查找异常处理器,没有跟在try块后的catch块是没有用的。try块可以包含任何C+语句,甚至包含整个函数。第7页/共56页2023/4/1385.2.4 catch块catch块的语法格式如下。catch(异常类型声明)异常处理语
5、句catch(异常类型声明)异常处理语句第8页/共56页2023/4/1395.2.4 catch块catch后括号中的异常类型声明可以是一个类型或一个对象声明,后边一对“”括住的是一组复合语句。一个catch块相当于一个以类型为单一参数的函数。catch块必须直接放在try块之后。catch语句与switch语句不同,它不需要在每个case语句后加入break用以中断后面程序的执行。一个catch块引入一个局部域,在catch块内声明的变量不能在catch块外引用。第9页/共56页2023/4/1310【例5.2】局部域声明的变量不能被局部域外引用例题。#includevoidmain()t
6、ry/一段可能引起异常的代码throw(出现异常!);catch(char*message)inty=1;cout处理了char*类型的异常endl;coutyendl;/编译错误,变量y未定义第10页/共56页2023/4/13115.2.5 异常处理模式C+的异常处理有两种基本模式:1终止模式异常抛出后,捕捉异常并退出导致异常的子程序或子系统,退出需要关闭适当的文件,析构适当的对象,释放适当的内存,处理需要处理的设备等,这种方法称为终止模式。缺省情况下,C+异常处理机制采用终止方法。【例5.3】捕捉异常后直接退出的例题。第11页/共56页2023/4/1312#includevoidfun
7、c2()/一段有可能引起异常的代码throw1;cout其它程序语句!endl;voidmain()try第12页/共56页2023/4/1313func2();/func2()抛出的异常值为1/程序抛出异常后的语句部分cout异常处理结束后继续执行!endl;catch(intx)/对异常的处理cout处理了int类型的异常endl;cout程序结束!endl;在采用终止模式情况下程序的运行结果为:处理了int类型的异常!程序结束!第13页/共56页2023/4/13145.2.5 异常处理模式2恢复模式异常抛出后,捕捉异常并试图去纠正或调整引起异常的条件,然后从发生异常的地方继续执行,这种
8、方法称为恢复模式。恢复模式实现起来非常困难,在实际应用中,除了一些特殊的领域外,一般都不采用恢复模式处理异常。第14页/共56页2023/4/13155.2.6 重新抛出在异常处理过程中也可能存在“单个catch子句不能完全处理这个异常”的情况。那么该异常处理器在做完局部能够做的事情后,会再一次抛出这个异常,让函数调用链中更上级的函数来处理,这个过程称作重新抛出(rethrow)重新抛出的语法形式如下:throw;重新抛出的还是原来捕捉到的那个异常。重新抛出只能出现在catch块中。第15页/共56页2023/4/1316【例5.4】重新抛出捕捉的异常例题。#includevoidfunc3(
9、intx)try/一段有可能引起异常的代码throwx;catch(intx)/如果异常参数x=0则进行处理,否则继续抛出if(x=0)/对异常的处理elsecout重新抛出异常!endl;第16页/共56页2023/4/1317throw;/重新抛出voidmain()tryfunc3(1);/程序其它部分catch(intx)/对异常的处理cout处理了int类型的异常!endl;第17页/共56页2023/4/1318程序运行结果为:重新抛出异常!处理了int类型的异常!有的情况下,异常处理器在重新抛出之前会对异常信号进行一些修改,这个修改能够影响更高级函数调用链中的异常处理器对该异常的
10、处理。5.2.6 重新抛出第18页/共56页2023/4/13195.2.7异常规范异常规范规定:随着函数声明列出该函数可能抛出的异常,并保证该函数不会抛出其它类型的异常。常见附带异常说明的函数说明有以下3种情况。(1)函数返回类型函数名(参数列表)throw(类型列表);(2)函数返回类型函数名(参数列表)throw();(3)函数返回类型函数名(参数列表);第一种情况,函数列出所有可能抛出的异常类型;第二种情况表示函数不会抛出任何类型的异常;第三种情况表示函数可能抛出任何类型的异常。异常规范并非强制规定,因此,没有在函数说明后附带异常说明并非语法错误。第19页/共56页2023/4/132
11、0【例5.6】异常规范的处理例题voidfunc5(intx)throw(int,char*)/x等于0抛出int型异常,x小于0抛出char*型异常,x大于0/什么也不做if(x=0)throw0;if(x0)throwerror;voidfunc6()throw()/本函数完成10个指令周期的延时,不抛出任何异常inti=0;while(i10)i+;第20页/共56页2023/4/13215.2.7异常规范有时,函数可能抛出没有列入异常规范的异常,出现这种情况时,系统分两种情况进行处理。(1)在函数内部(包括抛出异常的函数以及调用该函数的函数链中的任意函数)捕捉到了这个异常,进行了处理,
12、则程序可以继续执行。(2)异常被抛到函数外部,系统会调用C+标准库中定义的函数unexpected(),该函数的缺省行为是调用terminate(),终止程序的运行。当然,在C+中,可以改变unexpected()的缺省行为。第21页/共56页2023/4/13225.3 没有被捕捉的异常 根据异常匹配的规则,如果try块后面的所有的catch块都没有与某一异常相匹配,这时内层对异常的捕获失败,异常将进入更高层的上下文环境中进行匹配,这个过程一直进行直到在某个层次异常处理器与该异常相匹配,这时才认为捕获了这个异常。第22页/共56页2023/4/13235.3 没有被捕捉的异常如果任意层的异常
13、处理器都没有捕获到这个异常,那么这个异常最终会抛给main()函数,如果在main()中还没有找到合适的匹配,则称这个异常是“未捕捉的”或“未处理的”。如果一个异常未被捕捉,就会调用函数terminate(),终止本程序的运行。第23页/共56页2023/4/1324【例5.7】未被捕捉的异常处理例题#includevoidfunc7()throw0;voidmain()tryfunc7();catch(doubled)cout进行了异常处理!endl;第24页/共56页2023/4/1325例子5.7中,func7()函数中抛出了int型的异常,最后抛给了main()函数,在main()函数
14、中也没找到合适的匹配,于是终止本程序运行,main()函数catch块后边的程序其它部分不再执行。如果在所有函数之外的代码出现异常,比如全局对象的构造和析构等,如果有相应的异常处理器捕捉到抛出的异常,则异常处理后继续main()函数的执行,如果没有捕捉到抛出的异常,则终止本程序运行。5.3 没有被捕捉的异常 第25页/共56页2023/4/13265.4 catch(.)使用 C+在异常处理中提供了一个能捕捉所有异常的catch块。catch块的语法格式如下:catch()异常处理语句其中,列表中的“”表示可捕获所有的异常,但使用省略号就不可能有参数,也不可能知道所接受到的异常为何种类型。其它
15、部分和普通catch块完全一样。第26页/共56页2023/4/1327【例5.9】使用catch(.)语句的异常处理例题#includevoidfunc5(intx)throw(int)/x等于0抛出int型异常,x小于0抛出char*型异常if(x=0)throw0;if(x0)throwerror;voidmain()tryintx=0;coutx;第27页/共56页2023/4/1328func5(x);/程序其它部分catch(.)/对异常的处理cout处理了所有类型的异常!endl;cout程序结束!endl;程序运行结果如下:请输入一个int类型数据:0处理了所有类型的异常!第2
16、8页/共56页2023/4/13295.5 用类的对象传递异常 异常信息传递是指将throw语句抛出的异常参数传递到catch块中。但在实际应用中,由于抛出异常信息的需要,经常使用类的对象传递异常。使用对象传递异常还有以下2个好处:(1)在C+中,很好地实现了RTTI(Run-TimeTypeInformation)技术,使用对象传递异常,可以很好地完成异常对象的类型匹配。(2)在C+中,很好地实现了对象的构造、销毁、转存复制等技术,可以很好的实现异常信息的传递、修改和销毁等。同函数参数传递方式一样,异常参数的传递有3种方式:传值方式、引用方式和指针方式第29页/共56页2023/4/1330
17、5.5.1 传值方式传递异常对象 按传值方式传递异常对象时,被抛出的异常都是局部变量,而且是临时的局部变量。也就是说,每当在throw语句抛出一个异常对象时,不管构造的对象是什么性质的变量,此时它都会复制一份临时局部变量。【例5.10】按传值方式传递异常对象例题。#include#includeusingnamespacestd;第30页/共56页2023/4/1331classCMyException/异常类,该类的对象作为抛出异常时传递的异常参数。public:CMyException(stringn=none):name(n)/根据参数n构造一个名字为n的异常类对象cout“构造一个CM
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计
限制150内