首页 / 软件开发 / Delphi / 第十二章-异常处理与程序调试(二)(3)
第十二章-异常处理与程序调试(二)(3)2007-05-0712.3.5.1 定义异常对象类 异常是对象,所以定义一类新的异常同定义一个新的对象类型并无太大区别。由于缺省异常处理只处理从Exception或Exception子类继承的对象,因而自定义异常类应该作为Exception或其它标准异常类的子类。这样,假如在一个模块中引发了一个新定义的异常,而这个模块并没有包含对应的异常响应,则缺省异常处理机制将响应该异常,显示一个包含异常类名称和错误信息的消息框。下面是一个异常类的定义: typeEMyException = Class(Exception) ; 12.3.5.2 自引发异常 引发一个异常,调用保留字raise,后边跟一个异常类的实例。假如定义: typeEPasswordInvalid = Class(Exception); 则在程序中如下的语句将引发一个EPasswordInvalid异常: If Password <> CorrectPassword thenraise EPasswordInvalid.Create("Incorrect Password entered");异常产生时把System库单元中定义的变量ErrorAddr的值置为应用程序产生异常处的地址。在你的异常处理过程中可以引用ErrorAddr的值。在自己引发一个异常时,同样可以为ErrorAddr分配一个值。为异常分配一个错误地址需要使用保留字at,使用格式如下: raise EInstance at Address_Expession; 12.3.5.3 自定义异常的应用举例 下面我们给出一个利用自定义异常编程的完整实例。两个标签框(Label1、Label2)标示对应编辑框的功能。编辑框PassWord和InputEdit用于输入口令和数字。程序启动时Label2、InputEdit不可见。当在PassWord中输入正确的口令时,Label2、InputBox出现在屏幕上。此时Label1、PassWord隐藏。设计时,令Label2、InputEdit的Visible属性为False。通过设置PassWord的PassWordChar可以确定输入口令时回显在屏幕上的字符。自定义异常EInvalidPassWord和EInvalidInput分别用于表示输入的口令非法和数字非法。它们都是自定义异常EInValidation的子类。而EInValidation直接从Exception异常类派生。下面是三个异常类的定义。 typeEInValidation = class(Exception)publicErrorCode: Integer;constructor Create(Const Msg: String;ErrorNum: Integer);end;EInvalidPassWord = class(EInValidation)publicconstructor Create;end;EInvalidInput = class(EInValidation)publicconstructor Create(ErrorNum: Integer);end; EInValidation增加了一个公有成员ErrorCode来保存错误代码。错误代码的增加提供了很大的编程灵活性。对于异常类,可以根据错误代码提供不同的错误信息;对于使用者可以通过截取错误代码,在try...except模块之外来处理异常。从以上定义可以发现:EInvalidPassWord和EInvalidInput的构造函数参数表中没有表示错误信息的参数。事实上,它们保存在构造函数内部。下面是三个自定义异常类构造函数的实现代码。 constructor EInValidation.Create(Const Msg: String; ErrorNum: Integer);begininherited Create(Msg);ErrorCode := ErrorNum;end;constructor EInValidPassWord.Create;begininherited Create("Invalid Password Entered",0);end;constructor EInValidInput.Create(ErrorNum: Integer);varMsg: String;begincase ErrorNum of1:Msg := "Can not convert String to Number";2:Msg := "Number is out of Range";elseMsg := "Input is Invalid";end;inherited Create(Msg,ErrorNum);end; 对于EInvalidInput,ErrorCode=1表示输入的不是纯数字序列,而ErrorCode=2表示输入数值越界。口令检查是用户在PassWord中输入口令并按下回车键后开始的。实现代码在PassWord的OnKeyPress事件处理过程中: procedure TForm1.PassWordKeyPress(Sender: TObject; var Key: Char);constCurrentPassWord = "Delphi";beginif Key = #13 thenbegintryif PassWord.text <> CurrentPassWord thenraise EInvalidPassWord.Create;Label2.Visible := True;InputEdit.Visible := True;InputEdit.SetFocus;PassWord.Visible := False;Label1.Visible := False;excepton EInvalidPassWord dobeginPassWord.text := "";raise;end; end;Key:=#0;end;end; 同样,在InputEdit的OnKryPress事件处理过程中实现了输入数字的合法性检查: procedure TForm1.InputEditKeyPress(Sender: TObject; var Key: Char);varRes: Real;Code: Integer;beginif Key = #13 thenbegintryval(InputEdit.text,Res,Code);if Code <> 0 thenraise EInValidInput.create(1);if (Res > 1) or (Res < 0) thenraise EInValidInput.create(2);MessageDlg("Correct Input", mtInformation,[mbOk], 0);Key := #0;excepton E:EInValidInput dobeginInputEdit.text := "";MessageDlg(E.Message, mtWarning,[mbOk], 0);end;end;end;end; 由于异常响应后即被清除,所以要显示异常信息,需要另外的手段。在以上两段程序中我们采用了两种不同的方法:在口令合法性检查中,利用异常重引发由系统进行缺省响应;在输入数字合法性检查中,通过异常实例来获取异常信息并由自己来显示它。以上所举的是一个非常简单的例子,但从中已可以发现:使用自定义异常编程,为程序设计带来了很大的灵活性。