第8章 异常处理.docx
- 文档编号:2132290
- 上传时间:2022-10-27
- 格式:DOCX
- 页数:11
- 大小:238.11KB
第8章 异常处理.docx
《第8章 异常处理.docx》由会员分享,可在线阅读,更多相关《第8章 异常处理.docx(11页珍藏版)》请在冰豆网上搜索。
第8章异常处理
第8章异常处理
C++Builder支持C++异常处理、基于C的结构异常处理以及VCL异常处理。
注意本章中所用的关于C++异常处理及结构异常处理的例子通过命令行使用bcc32.exe可成功地编译并运行,而不是使用IDE。
在调用标准C++例程及对象时可用C++异常处理。
VCL异常处理可在IDE内进行。
实际上,尽管C++Builder支持C++异常处理和基于C的结构异常处理。
但使用C++Builder和VCL可开发包含内嵌异常处理的例程的应用程序,这些例程可以在出现错误时自动发送异常。
8.1C++异常处理
异常是指需要特殊处理的例外情况,包括运行时发生的错误,如除数为零,存储空间不足等。
异常处理提供了一种标准的方法以处理错误,发现可预知及不可预知的问题,及允许开发者识别、查出和修改错漏之处(bugs)。
8.1.1异常处理的ANSI规定
C++Builder异常处理支持ANSI/ISO提议的C++工作标准。
发送异常可允许你收集发送点的信息,这将有助于诊断异常发生的原因。
可使用异常处理程序来确定程序终止之前的操作。
只有同步异常(错误都由程序内部引起)可被处理。
外部事件(例如按下Ctrl+C组合键)不被认为是一个异常。
C++语言规定所有的异常都应在一个try-block中被发送。
这个块之后紧接着是一个或多个catch块,用于识别和处理try-block中发生的错误。
8.1.2异常处理语法
异常处理要求使用三个关键字:
try、catch及throw。
程序通过可能产生特殊状况的trying语句以准备捕捉异常。
当C++程序发送一个异常时,可将控制转移或throw到程序另外的被称为异常处理程序的、用于处理该类异常的部分中去。
这种处理程序被称为catch异常。
程序通过执行throw语句来发送异常。
throw语句通常在一个函数内发生。
throw"overflow";
在这个例子中,语句发送一个描述异常类型的对象,在这里,是一个算术运算溢出。
从而程序的另一部分可捕捉并处理这个异常对象。
要使用异常处理,需将代码封闭在一个try/catch结构中,try/catch结构的语法如下:
注意C程序中不支持try、catch及throw关键字。
一个由try确定的try-block后必须紧接着一个由catch确定的处理程序。
try-block是一段用于确定程序执行时的控制流的语句。
若一个异常在try-block中被发送,程序控制被转移到适当的异常处理程序。
处理程序是一段被设计来用于处理异常的代码。
C++语言要求至少有一个处理程序紧接着try-block。
程序应包括一个可处理程序中可能发生的各个异常的处理程序。
注意C程序中不支持try、catch及throw关键字。
一个由try确定的try-block后必须紧接着一个由catch确定的处理程序。
try-block是一段用于确定程序执行时的控制流的语句。
若一个异常在try-block中被发送,程序控制被转移到适当的异常处理程序。
处理程序是一段被设计来用于处理异常的代码。
C++语言要求至少有一个处理程序紧接着try-block。
程序应包括一个可处理程序中可能发生的各个异常的处理程序。
8.1.3声明异常
虽然C++允许异常可为任意类型,但异常对象还是很有用的。
异常对象可当作其他对象一样看待。
异常对象将异常发送点的信息携带到异常对象被捕捉的地方。
应用程序的用户在程序运行时遇到不正常的情况时会很需要这些信息。
由C++语言预定义的异常,在联机帮助中的“LibraryReference”中介绍。
8.1.4发送异常
可能发生异常的代码块需以try为前缀同时封闭在花括号内。
这表明程序准备检查异常。
若异常发生,则程序流中断,然后会发生:
·程序搜索匹配的处理程序。
·若找到处理程序,则栈在该点被打开。
·程序控制转到处理程序。
·若没有找到处理程序,可调用set_terminate()以提供终止处理程序,否则,程序会调用terminate函数。
若无异常被发送,程序正常执行。
当异常发生时,throw语句初始化一个T类型(匹配arg参数的类型)的临时对象在throw(Targ)中使用。
对象的其他拷贝可在编译器需要时生成。
因此,对于包含子对象的类来说,定义一个拷贝结构很有用(对于按位拷贝无须定义拷贝结构)。
示例
下列例子说明了几种发送异常的方法。
注意这些例子通过命令行使用bcc32.exe可成功地编译并运行,而不需使用IDE。
例1:
下例传递一个Out对象给处理程序。
例2:
下例只是将上例中的异常重新发送。
下例在没有处理程序存在是调用terminate
例3:
下例指定了festival和test可发送的异常列表。
其他异常不能从festival中被传递出去。
若festival产生了一个Out之外的异常,它被看作一个意外的异常,程序控制会转到例4中所示的unexpected函数。
例4:
下例说明test不应发送任何异常。
若test中的任何函数(例如操作符new)发送了一个异常,它应在test内被捕捉和处理。
否则,这个异常就是test规定之外的异常。
可调用set_unexpected()设置另外一个处理程序。
否则,unexpected函数将被调用。
当异常发生时,throw语句初始化一个T类型(匹配arg参数的类型)的临时对象在throw(Targ)中使用。
对象的其他拷贝可在编译器需要时生成。
因此,对于定义一个如下所示的异常对象的拷贝结构很有用。
8.1.5处理异常
异常处理程序由紧接在try-block之后的catch关键字确定。
关键字catch也可紧接在其他catch块之后。
程序发送的每个异常都必须被异常处理程序捕捉和处理。
当异常的类型与catch的条件语句中的类型匹配(或可转换)时,异常被处理程序捕捉。
一旦类型匹配成立,程序控制转到处理程序且栈被打开。
处理程序确定处理程序不正常状态的操作。
处理程序执行完毕后,程序会在当前的try-block中发送异常的那个处理程序后继续运行。
其他处理程序不会对当前异常做出反映。
goto语句可用于将程序控制跳出一个处理程序。
若程序提供异常处理程序失败,程序终止。
注意这些例子通过命令行使用bcc32.exe可成功地编译并运行,而不需使用IDE。
例1:
例2:
下例说明当捕捉到的异常是类层次结构的一部分,则需从最末的派生类开始。
例3:
下例中,catch(...)块可处理任何类型的异常。
这个块也是try-block中唯一的处理程序。
8.1.6异常规范
C++提供一种名为exceptionspecification的特性可将一个函数可能发送的异常在声明中列出。
exceptionspecification使用时类似于函数声明的后缀,句法如下:
这样的函数后缀不是函数类型的一部分。
因此,指向函数的指针不会受exceptionspecification的影响。
像这样的指针只检查函数返回值和参数类型。
因此,下列声明是合法的:
当重载虚拟函数时需要小心。
因为exceptionspecification不是函数类型的一部分,所以可能会破坏程序设计。
例1:
在下例中,定义的派生类BETA:
:
vfunc不发送任何异常,这偏离了原始的函数声明。
下例是带有异常规范的函数。
这样的函数的定义和所有的声明必须有一个包含相同的type-ids集的异常规范。
若函数发送一个规范中未列出的异常,程序会调用unexpected。
8.1.7异常处理的构造和析构
若不能成功地构造一个对象,类构造函数会发送异常。
当按值发送对象且异常被引发时,拷贝构造函数被调用。
拷贝构造函数在发送点初始化一个临时对象。
应用程序也可产生另外的拷贝。
如果构造函数发送了异常,对象的析构函数就不需要被调用。
析构函数仅为基类和那些在try-block中构造成功的对象调用。
为try-block中构造的throw语句后的对象调用析构函数的进程称为stackunwinding。
若析构函数在这个进程中引发一个异常且没有处理,则terminate被调用。
析构函数是缺省调用的,不过可通过使用-xd-编译器选项关闭缺省设置。
8.1.8未处理的异常
如果一个异常被发送但没有发现事件处理程序,程序调用terminate函数。
下例说明了程序中出现未处理的异常时如何处理。
8.1.9设置异常处理选项
表8-1是C++Builder编译器的异常处理选项。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第8章 异常处理 异常 处理