c基础知识异常处理机制实用实用教案_第1页
c基础知识异常处理机制实用实用教案_第2页
c基础知识异常处理机制实用实用教案_第3页
c基础知识异常处理机制实用实用教案_第4页
c基础知识异常处理机制实用实用教案_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

1、10.1 异常(ychng)的概念 异常概念的引入: 异常(exception)是程序可能检测到 的,运行时不正常的情况,如存储空间耗尽、数组越界、被0除等等。可以预见可能发生在什么地方,但是无法确知怎样发生和何时发生。特别在一个大型的程序(软件)中,程序各部分是由不同的小组编写的,它们由公共接口连起来,错误可能就发生在相互的配合(pih)上,也可能发生在事先根本想不到的个别的条件组合上。C+提供了一些内置的语言特性来产生(raise)或抛出(throw)异常,用以通知“异常已经发生”,然后由预先安排的程序段来捕获(catch)异常,并对它进行处理。这种机制(jzh)可以在C+程序的两个无关(

2、往往是独立开发)的部分进行“异常”通信。由程序某一部分引发了另一部分的异常,这一异常可回到引起异常的部分去处理(逆着程序函数的调用链)。第1页/共39页第一页,共40页。10.2 异常处理(chl)的机制测到栈满或空就抛出一个异常。测到栈满或空就抛出一个异常。template void Stack:Push(const T&data) if(IsFull() throw pushOnFull(data); /注意加了括号注意加了括号,是构造是构造(guzo)一个无名对象一个无名对象 elements+top=data; templateT Stack:Pop() if(IsEmpty(

3、) throw popOnEmpty(); return elementstop-; 注意注意pushOnFull是类,是类,C+要求抛出的必须是对象,所以必须有要求抛出的必须是对象,所以必须有“()”,即调用构造,即调用构造(guzo)函数建立一个对象。函数建立一个对象。异常异常(ychng)与异常与异常(ychng)抛出:抛出:以栈为例,异常以栈为例,异常(ychng)类声明如下类声明如下:class popOnEmpty.; /栈空异常栈空异常(ychng)class pushOnFull.; /栈满异常栈满异常(ychng)第2页/共39页第二页,共40页。10.2 异常处理(chl)

4、的机制throw表达式抛出异常为异常处理的第一步。在堆栈的压栈和出栈操作中发生错表达式抛出异常为异常处理的第一步。在堆栈的压栈和出栈操作中发生错误而抛出的异常,理所当然地应由调用堆栈的程序误而抛出的异常,理所当然地应由调用堆栈的程序(chngx)来处理。异常并非来处理。异常并非总是类对象,总是类对象,throw表达式也可以抛出任何类型的对象,如枚举、整数等等。但表达式也可以抛出任何类型的对象,如枚举、整数等等。但最常用的是类对象。最常用的是类对象。在C+中异常抛出与异常处理之间有一整套程序设计的机制。首先采用关键字try,构成一个try块(try block),它包含了抛出异常的语句(yj)。

5、当然也可以是包含了这样的调用语句(yj),该语句(yj)所调用的函数中有能够抛出异常的语句(yj)。异常处理机制:第3页/共39页第三页,共40页。10.2 异常(ychng)处理的机制int main() int a9=1,2,3,4,5,6,7,8,9,b9=0,i; stackistack(8); try for(i=0;i9;i+) istack.Push(ai); istack.PrintStack(); catch(pushOnFull)cerr”栈满”endl; try for(i=0;i9;i+)bi=istack.Pop(); catch(popOnEmpty)cerr”栈空

6、”endl; for(i=0;i9;i+) coutbit; coutendl; return 0; try块与块与catch子句的关系子句的关系(gun x)实例:实例:第4页/共39页第四页,共40页。10.2 异常处理(chl)的机制由catch字句捕获并处理异常是第二步。注意与catch语句分别匹配(ppi)的是在压栈和出栈成员函数模板中的throw语句,一个抛出pushOnFull类的无名对象,另一个抛出popOnEmpty类的无名对象。在编制程序时有一条惯例:把正常执行的程序与异常处理两部分分隔开来,这样使代码更易于(yy)跟随和维护。在上例中,我们可以把两个try块合成一个,而把

7、两个catch子句都放在函数最后。 说明:说明:这里有两个try块,分别对应压栈与出栈;也有两个catch子句(catch clause),分别处理压栈时的栈满和出栈时的栈空。 第5页/共39页第五页,共40页。10.2 异常处理(chl)的机制1如果没有异常发生,继续执行try块中的代码,与try块相关联 的catch子句被忽略,程序正常执行,main()返回0。2当第一个try块在for循环(xnhun)中抛出异常,则该for循环(xnhun)退出,try块也退出,去执行可处理pushOnFull异常的catch子句。istack.PrintStack()不再执行,被忽略。3如果第二个tr

8、y块调用Pop()抛出异常,则退出for和try块,去执行可处理popOnEmpty异常的catch子句。4当某条语句抛出异常时,跟在该语句后面的语句将被跳过。程序执行权交给处理异常的catch子句,如果没有catch子句能够处理异常,则交给C+标准库中定义的terminate()。流程控制流程控制(kngzh)规则:规则:第6页/共39页第六页,共40页。10.3 栈展开与异常栈展开与异常(ychng)捕捕获获catch子句由三部分组成:关键字catch、圆括号中的异常声明以及(yj)复合语句中的一组语句。catch子句不是函数(hnsh),所以圆括号中不是形参,而是一个异常类型声明,可以是

9、类型也可以是对象。catch子句的使用:它只有一个子句,没有定义和调用之分。使用时由系统按规则自动在catch子句列表中匹配。 catch子句可以包含返回语句(子句可以包含返回语句(return),也可不包含返回语句。),也可不包含返回语句。包含返回语句,则整包含返回语句,则整个程序结束个程序结束。而不包含返回语句,则执行。而不包含返回语句,则执行catch列表之后的下一条语句。列表之后的下一条语句。 catch子句子句说明:说明:当try块中的语句抛出异常时,系统通过查看跟在其后的catch子句列表,来查找可处理该异常的catch子句。第7页/共39页第七页,共40页。10.3 栈展开(zh

10、n ki)与异常捕获对应在throw表达式中,构造抛出对象(duxing)也要有实参:throw pushOnFull(data); /data即Push(const &data)中的参数datatemplate class pushOnFull T _value;public: pushOnFull(T i):_value(i) /或写为pushOnFull(T i)_value=i; T value()return _value; ;新的私有数据成员(chngyun)_value保存那些不能被压入栈中的值。该值即调用构造函数时的实参。catchcatch子句异常声明探讨:子句异常声

11、明探讨:异常声明中可以是一个对象声明。以栈为例。当栈满时,要求在异常对象中保存不能被压入到栈中的值,pushOnFull类可定义如下:第8页/共39页第八页,共40页。10.3 栈展开(zhn ki)与异常捕获 在catch子句中,要取得_value,须调用pushOnFull 中的成员函数value():catch(pushOnFull eObj) cerr”栈满”eObj.value()”未压入栈”endl; return 1;在catch子句的异常声明中声明了对象(duxing)eObj,用它来调用pushOnFull类的对象(duxing)成员函数value()。异常对象(duxing

12、)是在抛出点被创建,与catch子句是否显式要求创建一个异常对象(duxing)无关,该对象(duxing)总是存在,在catch子句中只是为了调用异常处理对象(duxing)的成员函数才声明为对象(duxing),不用类。*catch子句异常声明中采用对象只是一种形式。甚至(shnzh)异常并非一个类对象时,也可以用同样的格式,比如异常为一枚举量,这时就等效于按值传递,而不是调用类对象的公有成员。 第9页/共39页第九页,共40页。10.3 栈展开与异常(ychng)捕获catch子句的异常声明与函数参数声明类似,可以是按值传送,也可以是按引用传递。对大型类对象减少不必要的复制是很有意义(y

13、y)的,所以对于类类型的异常,其异常声明最好也是被声明为引用。如:catch(pushOnFull & eObj) cerr”栈满”eObj.value()”未压栈”endl; return 1; 使用引用类型的异常声明,catch子句能够修改异常对象,但仅仅是异常对象本身,正常程序部分的量并不会被修改。与一般类对象不同,实际上异常对象处理完后,生命期也就结束了。只有需要重新抛出(po ch)异常(在下一节中讨论),修改操作才有意义。 【例10.1】包含栈满或空异常的完整的程序。第10页/共39页第十页,共40页。10.3 栈展开与异常(ychng)捕获把程序的正常处理代码和异常处理代

14、码分离的最清楚(qng chu)的方法是定义函数try块(Function try Block)。这种方法是把整个函数包括在try块中。 一个函数try块把一组catch子句同一个函数体相关联。如果函数体中的语句抛出一个异常,则考虑跟在函数体后面的处理代码(di m)来处理该异常。函数try块对构造函数尤其有用。【例10.1_1】定义函数try块(Function try Block)。 函数函数trytry块的使用:块的使用:第11页/共39页第十一页,共40页。寻找匹配的catch子句有固定的过程:如果throw表达式位于try块中,则检查与try块相关联的catch子句列表,看是否有一个

15、子句能够处理该异常,有匹配的,则该异常被处理;找不到匹配的catch子句,则在主调函数(hnsh)中继续查找。如果一个函数(hnsh)调用在退出时带有一个被抛出的异常未能处理,而且这个调用位于一个try块中,则检查与该try块相关联的catch子句列表,看是否有一个子句匹配,有,则处理该异常;没有,则查找过程在该函数(hnsh)的主调函数(hnsh)中继续进行。即这个查找过程逆着嵌套的函数(hnsh)调用链向上继续,直到找到处理该异常的catch子句。只要遇到第一个匹配的catch子句,就会进入该catch子句,进行处理,查找过程结束。 第12页/共39页第十二页,共40页。10.3 栈展开与

16、异常(ychng)捕获在栈异常处理的例子中,对popOnEmpty,首先应在istack的成员函数Pop()中找,因为Pop()中没有try块,不存在catch子句,所以Pop()带着一个异常退出。下一步是检查调用Pop()的函数,这里是main(),在main()中对Pop()的调用位于一个try块中,则可用与该try块关联的catch子句列表中的某一个来处理,找到第一个popOnEmpty类型异常声明(shngmng)的catch子句,并进入该子句进行异常处理。 栈展开:栈展开: 因发生异常而逐步退出复合语句和函数定义因发生异常而逐步退出复合语句和函数定义(dngy)的过程,被称为栈展开的

17、过程,被称为栈展开(stack unwinding)。这是异常处理。这是异常处理的核心技术。的核心技术。异常对程序的影响通常不仅是在发生异常的那个局部范围中,而且可能逆调用链而上,甚至整个任务。因此,异常处理应该在其对程序影响的终结处进行,甚至是在调用该任务的菜单处进行。第13页/共39页第十三页,共40页。10.3 栈展开(zhn ki)与异常捕获在栈展开期间,在退出的域中有某个局部量是类对象,栈展开过程将自动调用该对象的析构函数,完成资源的释放。所以C+异常处理过程本质上反映的是“资源获取是由构造函数实现,而资源释放是由析构函数完成” 。采用面向对象的程序设计,取得(qd)资源的动作封装在

18、类的构造函数中,释放资源的动作封装在类的析构函数中,当一个函数带着未处理的异常退出时,函数中这种类对象被自动销毁,资源(包括动态空间分配的资源和打开的文件)释放。所以由文件重构对象应该放在构造函数中,把对象存入文件应该放在析构函数中。栈展开栈展开(zhn ki)(zhn ki)时资源时资源的释放的释放: :异常处理应该用于面向对象的程序设计。对非面向对象的程序设计如果函数动态获得过资源,因异常,这些资源的释放语句可能被忽略,则这些资源将永远不会被自动释放。第14页/共39页第十四页,共40页。10.3 栈展开与异常(ychng)捕获 异常不能够保持在未被处理的状态。异常表示一个程序不能够继续正

19、常执行,这是非常严重(ynzhng)的问题,如果没有找到处理代码,程序就调用C+标准库中定义的函数terminate()。异常对象的探讨:异常对象的探讨:异常对象是在异常对象是在throw表达式中建立并抛出:表达式中建立并抛出:throw表达式通过调用异常类的构造函数表达式通过调用异常类的构造函数创建一个临时对象,然后把这个临时对象创建一个临时对象,然后把这个临时对象复制到一个被称为异常对象(复制到一个被称为异常对象(exception object)的存贮区中,它保证会持续)的存贮区中,它保证会持续(chx)到异常被处理完。到异常被处理完。 第15页/共39页第十五页,共40页。10.3 栈

20、展开(zhn ki)与异常捕获函数调用和异常处理的区别:函数调用和异常处理的区别:建立函数调用所需要的全部信息在编译时已经获得,而异建立函数调用所需要的全部信息在编译时已经获得,而异常处理机制要求运行时的支持。对于普通函数调用,通过常处理机制要求运行时的支持。对于普通函数调用,通过函数重载解析过程,编译器知道函数重载解析过程,编译器知道(zh do)在调用点上哪个在调用点上哪个函数会真正被调用。但对于异常处理,编译器不知道函数会真正被调用。但对于异常处理,编译器不知道(zh do)特定的特定的throw表达式的表达式的catch子句在哪个函数中,以子句在哪个函数中,以及在处理异常之后执行权被转

21、移到哪儿。这些都在运行时及在处理异常之后执行权被转移到哪儿。这些都在运行时刻决定,异常是随机发生的,异常处理的刻决定,异常是随机发生的,异常处理的catch子句是逆子句是逆调用链进行查找,这与运行时的多态调用链进行查找,这与运行时的多态虚函数也是不虚函数也是不一样的。当一个异常不存在处理代码时,系统无法通知用一样的。当一个异常不存在处理代码时,系统无法通知用户,所以要有户,所以要有terminate()函数,它是一种运行机制,当函数,它是一种运行机制,当没有处理代码(没有处理代码(catch子句)能够匹配,被抛出的异常时子句)能够匹配,被抛出的异常时由它通知用户。由它通知用户。第16页/共39

22、页第十六页,共40页。10.4 异常的重新(chngxn)抛出和catch_all子句(选读) rethrow表达式仍为:throw; 但仅有一个关键字,因为异常类型在catch语句中已经有了,不必再指明。被重新抛出的异常就是(jish)原来的异常对象。但是重新抛出异常的catch子句应该把自己做过的工作告诉下一个处理异常的catch子句,往往要对异常对象做一定修改,以表达某些信息,因此catch子句中的异常声明必须被声明为引用,这样修改才能真正做在异常对象自身中,而不是副本中。 异常的重新抛出与连续处理:异常的重新抛出与连续处理:当当catch语句捕获一个异常后,可能不能完全语句捕获一个异常

23、后,可能不能完全(wnqun)处理异常,完成某些操作后,该异常处理异常,完成某些操作后,该异常必须由函数链中更上级的函数来处理,这时必须由函数链中更上级的函数来处理,这时catch子句可以重新抛出(子句可以重新抛出(rethrow)该异常,把)该异常,把异常传递给函数调用链中更上级的另一个异常传递给函数调用链中更上级的另一个catch子句,由它进行进一步处理。子句,由它进行进一步处理。第17页/共39页第十七页,共40页。10.4 异常的重新抛出(po ch)和catch_all子句(选读)通用通用catch子句子句(catch_all):catch(.)代码代码*/ 任何异常任何异常(ych

24、ng)都可以进入这个都可以进入这个catch子句。这子句。这里的三个点称为省略号。花括号中的复合语句用里的三个点称为省略号。花括号中的复合语句用来执行指定操作。来执行指定操作。异常发生后按栈展开(stack unwinding)退出,动态分配的非类(fi li)对象资源不会自动释放的,通常在catch_all子句中释放。void fun1() int *res; res=new int100; /定义一个资源对象 try /代码包括使用资源res和某些可能引起异常抛出的操作 /异常可能有多种 catch(.) /不论是那种异常都在此释放 delete res; /释放资源对象res throw

25、; /重新抛出异常 delete res; /正常退出前释放资源对象res;第18页/共39页第十八页,共40页。10.4 异常的重新抛出(po ch)和catch_all子句(选读) catch_all子句可以单独使用,也可以与其它catch子句联合使用。如果联合使用,它必须放在相关catch子句表的最后。 catch子句被检查的顺序与它们在try块之后排列顺序相同,一旦找到了一个匹配,则后续的catch子句将不再检查,按此规则,catch_all子句(catch(.))处理表前面所列各种异常之外的异常。 如果只用catch_all子句进行(jnxng)某项操作,则其他的操作应由catch子

26、句重新抛出异常,逆调用链去查找新的处理子句来处理,不能在子句列表中再安排一个处理同一异常的子句,因为第二个子句是永远执行不到的。通用通用(tngyng)catch子句的应用:子句的应用:第19页/共39页第十九页,共40页。10.5 异常(ychng)和继承定义(dngy)一个称为Excp的基类,由它来打印错误信息:class Excp public:void print(string msg)cerrmsgendl; ;再从该基类派生出两个异常类:class stackExcp:public Excp.; /栈异常类的基类class mathExcp:public Excp.; /数学库异常

27、的基类进一步派生出其他异常类:class popOnEmpty:public stackExcp.; /栈空退栈异常class pushOnFull:public stackExcp.; /栈满压栈异常class zeroOp:public mathExcp.; /数学库零操作异常class divideByZero:public mathExcp.; /数学库被零除异常 异常的层次结构:异常的层次结构:在在C+程序中,表示异常的类通常被组成程序中,表示异常的类通常被组成(z chn)为一个组(即如在前面各节讨论的那样)为一个组(即如在前面各节讨论的那样)或者一个层次结构。或者一个层次结构。形

28、成了三层结构。第20页/共39页第二十页,共40页。10.5 异常(ychng)和继承在层次结构下,异常的抛出(po ch)会有一些不同,以下做法是错的:if(full() pushOnFull except(data); stackExcp *pse=&except; /pse指向的类对象为pushOnFull throw *pse; /抛出(po ch)的异常对象的类型为stackExcp这里被创建的异常类对象(duxing)是stackExcp类类型,尽管pse指向一个实际类型为pushOnFull的对象(duxing),但那是一个临时对象(duxing),复制到异常对象(dux

29、ing)的存储区中时创建的却是stackExcp类的异常对象(duxing)。所以该异常不能被pushOnFull类型的catch子句处理。层次结构异常的抛出:层次结构异常的抛出:第21页/共39页第二十一页,共40页。10.5 异常(ychng)和继承在处理类类型异常(ychng)时,catch子句的排列顺序是非常重要的。catch(pushOnFull). /处理pushOnFull异常(ychng)catch(stackExcp). /处理栈的其他异常(ychng)catch(Excp). /处理一般异常(ychng)派生类类型的catch子句必须先出现,以确保只有在没有其他catch子

30、句适用时,才会进入基类类型的catch子句。异常(ychng)catch子句不必是与异常(ychng)最匹配的catch子句,而是最先匹配到的catch子句,就是第一个遇到的可以处理该异常(ychng)的catch子句。所以在catch子句列表中最特化的(匹配条件最严格的)catch子句必须先出现。catchcatch子句的排列顺序:子句的排列顺序:第22页/共39页第二十二页,共40页。10.5 异常(ychng)和继承类层次结构的异常(ychng)同样可以重新抛出(rethrow),把一个异常(ychng)传递给函数调用列表中更上层的另一个catch子句:throw;类层次结构下的异常重新

31、类层次结构下的异常重新(chngxn)(chngxn)抛出:抛出:重新抛出的异常仍是原来的异常对象。如果程序中抛出了pushOnFull类类型的异常,而它被基类的catch子句处理,并在其中再次被抛出,那么这个异常仍是pushOnFull类的异常,而不是其基类的异常。第23页/共39页第二十三页,共40页。10.5 异常(ychng)和继承在基类catch子句处理(chl)的是异常对象的基类子对象的一份副本,该副本只在该catch子句中被访问,重新抛出的是原来的异常对象。这个放在异常对象存储区中的异常的生命期应该是在处理(chl)该异常的一系列的子句中最后一个退出时才结束,也就是直到这时,才由

32、异常类的析构函数来销毁它。这一系列的子句是由重新抛出联系起来的。【例10.2】异常层次结构中的虚函数。为了调用派生类对象的虚拟函数,异常声明(shngmng)必须为一个指针或引用。 虚函数是类层次结构中多态性的基本手段,异常类层次结构中也可以定义虚拟函数。 第24页/共39页第二十四页,共40页。10.6 异常(ychng)规范一个函数的异常规范的违例只能在运行时才能被检测出来。如果在运行时,函数抛出了一个没有被列在它的异常规范中的异常时(并且函数中所抛出的异常,没有在该函数内部处理)则系统调用C+标准库中定义的函数unexpected()。仅当函数中所抛出的异常,没有在该函数内部处理,而是逆

33、调用链回溯寻找匹配的catch子句的时候,异常规范才起作用。如果异常规范为throw(),则表示(biosh)不得抛出任何异常。异常规范(exception specification)提供了一种方案,可以随着(su zhe)函数声明列出该函数可能抛出的异常,并保证该函数不会抛出任何其他类型的异常,在stack类定义中可有: void Push(const T&data) throw(pushOnFull) ;T Pop() throw(popOnEmpty); 成员函数类内声明和类外定义必须必须在两处都有相同的异常规范,同样的异常规范。异常规范的引入:异常规范的引入:第25页/共39

34、页第二十五页,共40页。10.6 异常(ychng)规范class CBasepublic: virtual int fun1(int) throw(); virtual int fun2(int) throw(int); virtual string fun3() throw(int,string);class CDerived:public CBasepublic: int fun1(int) throw(int); /错!异常(ychng)规范不如throw()严格 int fun2(int) throw(int); /对!有相同的异常(ychng)规范 string fun3() th

35、row(string); /对!异常(ychng)规范比 throw(int,string)更严格 虚函数中的异常规范:派生类的虚拟函数的异常规范必须与基类虚函数的异常一样或更严格。因为当派生类的虚函数被指向基类类型的指针调用(dioyng)时,保证不会违背基类成员函数的异常规范。 第26页/共39页第二十六页,共40页。10.7 C+标准(biozhn)库的异常类层次结构(选读)exception类的接口如下(rxi):namespace std /注意在名字空间域std中 class exception public: exception() throw() ; /默认构造函数 excep

36、tion(const exception &) throw() ; /复制构造函数 exception &operator=(const exception&) throw() ; /复制赋值操作符 virtual exception() throw() ; /析构函数 virtual const char* what() const throw() ; /返回一个C风格的字符串,目的是为抛出的异常提供文本描述 ;C+标准库中的异常层次的根类被称为标准库中的异常层次的根类被称为(chn wi)exception,定义在库的,定义在库的头文件头文件中中第27页/共39页第

37、二十七页,共40页。10.7 C+标准(biozhn)库的异常类层次结构(选读)C+C+标准库提供的逻辑异常:标准库提供的逻辑异常:invalid_argumentinvalid_argument异常,接收到一个无效的实参,抛出该异常,接收到一个无效的实参,抛出该异常。异常。out_of_rangeout_of_range异常,收到一个不在预期范围中的实参,则异常,收到一个不在预期范围中的实参,则抛出。抛出。length_errorlength_error异常,报告企图产生异常,报告企图产生“长度长度(chngd)(chngd)值超出值超出最大允许值最大允许值”的对象的对象domain_err

38、ordomain_error异常,用以报告域错误(异常,用以报告域错误(domain errordomain error)。)。C+C+标准库提供标准库提供(tgng)(tgng)的运行时异常:的运行时异常:range_errorrange_error异常,报告内部计算中的范围错误。异常,报告内部计算中的范围错误。overflow_erroroverflow_error异常,报告算术溢出错误。异常,报告算术溢出错误。underflow_errorunderflow_error异常,报告算术下溢错误。异常,报告算术下溢错误。以上三个异常是由以上三个异常是由runtime_errorruntime

39、_error类派生的。类派生的。bad_allocbad_alloc异常。当异常。当new()new()操作符不能分配所要求的存操作符不能分配所要求的存储区时,会抛出该异常。它是由基类储区时,会抛出该异常。它是由基类exceptionexception派生的。派生的。【例例10.3】为类模板为类模板Array重新定义下标操作符重新定义下标操作符,如果索引值越界,它会抛出一个,如果索引值越界,它会抛出一个out_of_range类型的异常。类型的异常。第28页/共39页第二十八页,共40页。第十章第十章 异常异常(ychng)(ychng)处理处理完完谢谢(xi xie)!第29页/共39页第二

40、十九页,共40页。 例例10.1 10.1 堆栈异常堆栈异常(ychng)(ychng)处理处理templateclass pushOnFull /栈满异常(ychng)声明T _value;public:pushOnFull(T i)_value=i;T value()return _value;void print()cerr栈满,value()未压入栈endl;templateclass popOnEmpty/栈空异常(ychng)声明public:void print()cerr栈已空,无法出栈endl;第30页/共39页第三十页,共40页。 例例10.1 10.1 堆栈异常堆栈异常(

41、ychng)(ychng)处理处理templateclass Stackint top; /栈顶指针(下标)T *elements; /动态建立的数值int maxSize; /栈最大允纳的元素个数public:Stack(int=20); /栈如不指定大小,设为20元素Stack()delete elements;void Push(const T &data) throw(pushOnFull); /压栈T Pop() throw(popOnEmpty); /弹出,top-T GetElem(int i)return elementsi; /返回指定元素void MakeEmpty

42、()top= -1; /清空栈bool IsEmpty() constreturn top= -1; /判栈空bool IsFull() constreturn top=maxSize-1; /判栈满void PrintStack(); /输出栈内所有(suyu)数据;第31页/共39页第三十一页,共40页。 例例10.1 10.1 堆栈异常堆栈异常(ychng)(ychng)处理处理template void Stack:Push(const T &data)if(IsFull() throw pushOnFull(data); /栈满则抛出异常elements+top=data;

43、/栈顶指针先加1,元素再进栈,top是指向栈顶元素templateT Stack:Pop() if(IsEmpty() throw popOnEmpty(); /栈已空则不能退栈,抛出异常return elementstop-;/返回(fnhu)栈顶元素,同时栈顶指针退1第32页/共39页第三十二页,共40页。 例例10.1 10.1 堆栈异常堆栈异常(ychng)(ychng)处理处理int main()int a9=1,2,3,4,5,6,7,8,9, b9=0,i;Stackistack(8);tryfor(i=0;i9;i+) istack.Push(ai); /到a8时栈满,异常(y

44、chng)istack.PrintStack();catch(pushOnFull&eObj)eObj.print();tryfor(i=0;i9;i+) bi=istack.Pop();catch(popOnEmpty&eObj) eObj.print();for(i=0;i9;i+) coutbit;coutendl;return 0;第33页/共39页第三十三页,共40页。 例例10.1_110.1_1函数函数(hnsh)try(hnsh)try块块(Function try BlockFunction try Block)int main()tryint a9=1,2,

45、3,4,5,6,7,8,9, b9=0,i;Stack istack(8);for(i=0;i9;i+) istack.Push(ai); /到a8时栈满,异常(ychng)istack.PrintStack();for(i=0;i9;i+) bi=istack.Pop();for(i=0;i9;i+) coutbit; /发生异常(ychng)后不会执行coutendl;return 0;catch(pushOnFull & eObj)eObj.print();return 1;catch(popOnEmpty & eObj)eObj.print();return 2;第34页/共39页第三十四页,共40页。 例例10.2 10.2 异常异常(ychng)(ychng)层次结层次结构中的虚函数构中的虚函数class Excppublic: virtual void print()cerr发生(fshng)异常endl;class stackExcp:public Excppublic: virtual void print()cerr栈发生(fshng)异常endl;class pushOnF

温馨提示

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

评论

0/150

提交评论