在应用程序开发中如何检测处理程序的运行错误是一个很重要的问题在 Delphi 的集成开发环境( IDE )中提供了一个完善的内置调试器可以帮助你发现大部分程序错误但并不是所有的错误都可以被发现而且当程序涉及到与外设的数据交换或操作外设如要求用户输入读写磁盘等时错误的发生是程序无法控制的如输入非法字符磁盘不能读写等这些情况不仅会导致应用程序异常中止而且可能引起系统的崩溃针对这些问题Delphi同时提供了一套强大的异常处理机制巧妙地利用它可以使你的程序更为强健使用更为友好
虽然Delphi为应用程序提供了一套缺省的自动异常处理机制即当前模块发生错误后退出当前模块并给出错误信息而并不立即引起应用程序的中止但当应用程序执行的过程性很强时仅仅利用这种方法是不够的而且很容易导致程序执行的不可预测性
Delphi异常处理机制与异常类
Delphi异常处理机制建立在保护块(Protected Blocks)的概念上所谓保护块是用保留字try和end封装的一段代码保护块的作用是当应用程序发生错误时自动创建一个相应的异常类(Exception)程序可以捕获并处理这个异常类以确保程序的正常结束以及资源的释放和数据不受破坏如果程序不进行处理则系统会自动提供一个消息框
异常类是Delphi异常处理机制的核心也是Delphi异常处理的主要特色下面我们对异常类的概念和体系进行详细的介绍
Delphi提供的所有异常类都是类Exception的子类用户也可以从Exception派生一个自定义的异常类
Exception类的定义如下对于不常用的成员没有列出
{SysUtils 单元中}
Exception = class(TObject)
private
FMessage: PString;
FHelpContext: Longint;
function GetMessage: String;
procedure SetMessage(const Value: String)
public
constructor Create(const Msg: String)
constructor CreateFmt(const Msg: String; const Args: array of const)
destructor Destroy; override;
property HelpContext: Longint
property Message: String;
property MessagePtr: PString;
end;
Exception的一系列构造函数中最重要的参数是显示的错误信息而数据成员中最重要的也是可被引用的消息字符串(messagemessagePtr) 这些信息分别对自定义一个异常类和处理一个异常类有重要作用
Delphi提供了一个很庞大的异常类体系这些异常类几乎涉及到编程的各个方面从大的方面我们可以把异常类分为运行时间库异常对象异常部件异常三类下面我们分别进行介绍
运行时间库异常类(RTL Exception)
运行时间库异常可以分为七类它们都定义在SysUtils库单元中
I/O异常
I/O异常类EInOutError是在程序运行中试图对文件或外设进行操作失败后产生的它从Exception派生后增加了一个公有数据成员ErrorCode用于保存所发生错误的代码这一成员可用于在发生I/O异常后针对不同情况采取不同的对策
当设置编译指示{$I } 时不产生I/O异常类而是把错误代码返回到预定义变量IOResult中
堆异常
堆异常是在动态内存分配中产生的包括两个类EOutOfMemory和EInvalidPointer
表 堆异常类及其产生原因
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
异常类 引发原因
─────────────────────────────────
EOutOfMemory 没有足够的空间用于满足所要求的内存分配
EInvalidPointer 非法指针一般是由于程序试图去释放一个业已释放的指针而引起的
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
整数异常
整数异常都是从一个EIntError类派生的但程序运行中引发的总是它的子类EDivByZeroERangeErrorEIntOverFlow
表 整数异常及其产生原因
━━━━━━━━━━━━━━━━━━━━━
异常类 引发原因
─────────────────────
EDivByZero 试图被零除
ERangeError 整数表达式越界
EIntOverFlow 整数操作溢出
━━━━━━━━━━━━━━━━━━━━━━
ERangeError当一个整数表达式的值超过为一个特定整数类型分配的范围时引发比如下面一段代码将引发一个ERangeError异常
var
SmallNumber: ShortInt;
X Y: Integer;
begin
X := ;
Y := ;
SmallNumber := X * Y;
end;
特定整数类型包括ShortIntByte以及与整数兼容的枚举类型布尔类型等例如
type
THazard = ( Safety Marginal Critical Catastrophic )
var
Haz: THazard;
Item: Integer;
begin
Item:= ;
Haz:= THazard ( Item )
end;
由于枚举数越界而引发一个ERangeError异常
数组元素越界也会引发一个ERangeError异常如
var
Values: array[] of Integer;
i: Integer;
begin
for i := to do
Values[i] := i;
end;
ERangeError异常只有当类型检查打开时才会引发这可以在代码中包含{$R+} 编译指示或设置IDE Option|Project的Range_Checking Option选择框
[] [] [] []