C课件第12章异常处理.ppt_第1页
C课件第12章异常处理.ppt_第2页
C课件第12章异常处理.ppt_第3页
C课件第12章异常处理.ppt_第4页
C课件第12章异常处理.ppt_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

第12章 异常处理,本章要点: 异常处理的概念和基本思想; C+异常处理的实现方法; C+异常处理中的构造与析构;,本章内容,12.1 异常处理机制 12.2 异常处理的实现 12.3 异常处理中的构造与析构 12.4 应用举例,异常处理机制(1),异常的概念 异常就是程序在运行的过程中,由于使用环境的变化以及用户的不当操作而产生的错误。例如,内存不足时,应用程序请求分配内存;请求打开硬盘上不存在的文件;程序中出现了以零为除数的错误;打印机未打开,调制解调器掉线等,导致程序运行中挂接这些设备失败等等,都会引发异常。对这些错误,应用程序如果不能进行合适的处理,将会使程序变得非常脆弱,甚至不可使用。因此,对于这些可以预料的错误,在程序设计时,应编制相应的预防代码或处理代码,以便防止异常发生后造成严重后果。一个应用程序,既要保证其正确性,还应有容错能力,也就是说,既要在正确的应用环境中、用户操作正确时运行正常、正确,而且要在应用环境出现意外或用户操作不当时,也应有合理的反应。 在C+中,异常是指从发生问题的代码区域传递到处理问题的代码区域的一个对象。,异常处理机制(2),异常处理的基本思想 1. 小型程序在出现异常时,一般是将程序立即中断运行,无条件释放所有资源。 如:,例12.1 以下程序当除数为零时,停止运行并给出提示信息 #include #include double fuc(double x, double y) if(y=0) cerr“error of dividing zero.n“; exit(1); return x/y; void main() fuc(2,3); fuc(4,0);,当除数为零时给出提示信息并停止运行,异常处理机制(3),2. 大中型程序中,上述处理方法就过于简单粗糙。这是因为在大中型程序中,函数之间有着明确的分工和复杂的调用关系。发现错误的程序往往在函数调用链的低层,这样,简单地在发现错误的函数中处理异常,就没有机会把调用链中的上层函数已经完成的一些工作做妥善的善后处理。例如,上层函数已经申请了堆对象,那么释放堆对象的工作显然不能在底层函数中处理,从而使程序不能正常运行。因此,对于大中型程序来说,在程序运行中一旦发生异常,应该允许恢复和继续运行。恢复是指把产生异常的错误处理掉,中间可能要涉及一系列函数调用链的退栈,对象的析构,资源的释放等。继续运行是指异常处理之后,在紧接着异常处理的代码区域中继续运行。,异常处理机制(4),处理异常的基本思想是:在底层发生的问题,逐级上报,直到有能力可以处理异常的那级为止。即在应用程序中,若某个函数发现了错误并引发异常,这个函数就将该异常向上级调用者传递,请求调用者捕获该异常并处理该错误。如果调用者不能处理该错误,就继续向上级调用者传递,直到异常被捕获错误被处理为止。如果程序最终没有相应的代码处理该异常,那么该异常最后被操作系统所接受,操作系统就简单地终止程序运行。 如右图:,称为函数调用链,只在调用链中传递异常! 成为异常处理链,异常处理的实现(1),C+异常处理的步骤是: 1定义异常(try语句块) try /将可能产生异常的语句放在try语句块中 2定义异常处理(catch语句块) 将处理异常的语句放在catch语句块中,以便异常被传递来时处理。通常,异常处理是紧接在try语句块后的若干个相邻的catch语句,每一个catch语句的格式是: catch(异常类型1) /异常处理语句块1 ,异常处理的实现(2),3抛弃异常(throw语句) 检测是否产生异常,若是,则抛弃异常。抛弃异常语句的格式是: throw 表达式;, throw 表达式 ,try 可能出现异常的语句块 catch(异常类型声明1) 异常处理语句块1 catch(异常类型声明2) 异常处理语句块2 catch(异常类型声明n) 异常处理语句块n ,如果到此处还没有找到,则将异常交给本语句所在函数的调用者。,如果表达式的类型和异常类型2相同或相容,执行相应语句后转到第n个catch 之后,如果此处有其他语句,则不进行匹配查找,如果此处有其他语句,则停止匹配查找,异常处理的实现(3),例12.2 处理文件打不开的异常 #include #include #include void main() ifstream source(“c:abc.txt“); /打开文件 char line128; try /定义异常 if (source.fail() throw “abc.txt“; /抛掷异常 catch(char * s) /定义异常处理 cout“error opening the file “sendl; exit(1); while(!source.eof() source.getline(line, sizeof(line); coutlineendl; source.close(); ,打开文件失败,抛掷异常,捕获字符指针类异常,并将值接收到s中,如果不需要详细信息,该处形参可以只说明类型。,异常处理的实现(4),异常处理的执行过程是: 1程序通过正常的顺序执行到try语句,然后执行try语句块内的程序段。 2如果在try语句块执行期间没有发生异常(也就是说没有执行到throw语句),则catch语句块不被执行。 3如果在try语句块执行期间或在该语句块直接或间接调用的任何函数中发生了异常,并将异常抛掷,则该异常将沿调用链上传,直到找到与该异常类型相匹配的catch语句块来处理异常。异常处理后,执行所有catch语句块的后续程序。 4如果未找到与该异常类型相匹配的catch语句块,则由系统终止程序的运行。,异常处理的实现(5),异常处理时注意的问题: 1 C+只理会放在try语句块内受监控的过程的异常,那些不受监控的过程的异常,C+是不会处理的。 2在try语句块之后必须紧跟一个或多个catch语句块,以便对发生的异常进行处理。在try语句块出现之前,不能出现catch语句块。 3catch语句的括号中只能有一个形参,但该形参是可选的,而形参的数据类型不能缺省必须保留,因为捕获是利用数据类型的匹配实现的。形参可以是“”,表示捕获所有的,应将它放置在所有的catch语句之后 。 4Throw语句的表达式可以省略,其含义是重新向上抛掷正在处理的异常。通常用于在catch语句中进行部分处理后,要求调用链上端继续处理该异常的情形。 5抛弃异常与处理异常可以放在不同的函数中。 6 C+允许对函数进行异常声明,即:在声明中注明函数可能抛弃的异常类型,其语法为: 返回值类型 函数名(形参列表)throw(异常类型1,异常类型2,),异常处理的实现(6),例12.3 处理除零异常。 #include double Div(double, double); void main() try /定义异常 cout“7.3/2.0=“Div(7.3,2.0)endl; cout“7.3/0.0=“Div(7.3,0.0)endl; cout“7.3/1.0=“Div(7.3,1.0)endl; catch(double) /定义异常处理 cout“exception of deviding zero.n“; cout“that is ok.n“; double Div(double a, double b) if (b=0.0) throw b; /抛掷异常 return a/b; ,运行结果为: 7.3/2.0=3.65 exception of deviding zero. that is ok.,从运行结果可知此语句没有被执行,处理完异常后从此处继续执行,可以声明为: double Div(double x, double y) throw(int);,异常处理中的构造与析构,C+异常处理的真正能力不仅在于它能处理各种不同类型的异常,还在于它具有在异常抛弃前为构造的所有局部对象自动调用析构函数的能力。 当在程序中找到一个匹配的catch异常处理后,如果catch()语句的异常类型声明是一个值参数,则其初始化方式是复制被抛弃的异常对象;如果catch()语句的异常类型声明是一个引用,则其初始化方式是使该引用指向异常对象。 当catch()语句的异常类型参数被初始化后,便开始了栈的展开过程,包括从对应的try语句块开始到异常被抛掷之间所构造的局部对象进行析构。析构的顺序与构造的顺序相反。然后程序从最后一个catch之后开始恢复执行。,void fuc1() int s=0; demo d; throw s; void fuc2() expt e; fuc1(); void main() try fuc2(); catch(int) cout“catch int exceptionn“; cout“continue main()“endl; ,例12.4 使用带析构的类的异常处理。 #include class expt public: expt() cout“structor of exptn“; expt() cout“destruct of exptn“; ; class demo public: demo() cout“structor of demon“; demo() cout“destruct of demon“; ;,异常处理中的构造与析构例,定义了局部对象d,运行结果: structor of expt structor of demo destruct of demo destruct of expt catch int exception continue main(),定义了局部对象e,应用举例,例8-5 处理结构类型的异常。 #include struct aircraft char *aircrafttype; float len; ; void myfuc() aircraft a; a.aircrafttype=“queen“; a.len=125; throw a; void main() try myfuc(); catch(aircraft b) cout“ aircraft type is:“b. aircrafttype“n“; ,运行结果: aircraft type is:queen,应用举例,例12.6 异常捕获链演示 #include void fc() try throw “sos“; catch(int) cout“sos int“endl; trythrow 1; catch(const char * )cout“sos string“endl; void fb() int *q=new int100; tryfc(); catch(.)delete q;throw; void fa()

温馨提示

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

评论

0/150

提交评论