当前位置: 首页 > 学习 > 电脑学习 > 程序设计 > Delphi > 基础教程 > 正文

Delphi 异常处理与程序调试(三)

http://www.zk168.com.cn  招考学习网 2006-4-7 9:40:22
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--

12.3 异常响应 

  异常响应为开发者提供了一个按自己的需要进行异常处理的机制。try…except …end形成了一个异常响应保护块。与finally不同的是:正常情况下except 后面的语句并不被执行,而当异常发生时程序自动跳到except,进入异常响应处理模块。当异常被响应后异常类自动清除。

  下面的例子表示了文件打开、删除过程中发生异常时的处理情况: 

uses Dialogs;

var

F: Textfile;

begin

OpenDialog1.Title := 'Delete File';

if OpenDialog1.Execute then

begin

AssignFile(F, OpenDialog1.FileName);

try

Reset(F);

if MessageDlg('Erase ' +OpenDialog1.FileName + '?',

mtConfirmation, [mbYes, mbNo], 0) = mrYes then

begin

System.CloseFile(F);

Erase(F);

end;

except

on EInOutError do

MessageDlg('File I/O error.', mtError, [mbOk], 0);

on EAccessDenied do

MessageDlg('File access denied.', mtError, [mbOk], 0);

end;

end;

end.

  保留字on…do用于判断异常类型。必须注意的是:except后面的语句必须包含在某一个on…do模块中,而不能单独存在。这又是同finally不同的一个地方。 

12.3.1 使用异常实例 

  上面所使用的异常响应方法可总结为如下的形式: 

  on ExceptionType do

{响应某一类的异常} 

  这种方法唯一使用的信息是异常的类型。一般情况下这已能满足我们的需要。但我们却无法获取异常实例中包含的信息,比如异常消息、错误代码等。假设我们需要对它们进行处理,那么就必须使用异常实例。

  为了使用异常实例,需要为特定响应模块提供一个临时变量来保存它: 

  on EInstance : ExceptionType do  … 

  在当前响应模块中我们可以象使用一个普通对象那样来引用它的数据成员。但在当前响应模块之外不被承认。

  下面的代码用于获取异常消息并按自己的方式显示它: 

{窗口中包括一个ScrollBar部件,一个Button部件} 

procedure TErrorForm.Button1Click(Sender: TObject);

begin

try

ScrollBar1.Max := ScrollBar1.Min-1;

except

on E: EInvalidOperation do

MessageDlg('Ignoring Exception:'+E.Message,

mtInformation,[mbOK],0);

end;

end; 

12.3.2 提供缺省响应 

  在异常响应模块中,一般我们只对希望响应的特定异常进行处理。如果一个异常发生而响应模块并没有包含对它的处理代码,则退出当前响应模块,异常类仍被保留。

  为了保证任何异常发生后都能在当前响应模块中被清除,可以定义缺省响应: 

try

{程序正常功能}

except

on ESomething do

{响应特定异常}

else

{提供缺省响应}

end; 

由于else可以响应任何异常,包括我们一无所知的异常,因此在缺省响应中最好只包括诸如显示一个消息框之类的处理,而不要改变程序的运行状态或数据。 

12.3.3 响应一族异常 

  诸如

    on ExceptionType do

的异常响应语句不仅可响应本类异常,而且可以响应子类异常。对于象EIntError、EMathError等系统不会引发的异常,它们将只响应其子类异常。而对于象

   on Exception do

这样的语句将会对任何异常进行响应。

  下面一段代码对整数越界异常进行单独处理,而对其它整数异常进行统一处理: 

  try

{整数运算}

except

on ERangeError do

{越界处理}

on EIntError do

{其它整数异常处理}

end; 

由于异常在处理后即被清除,因而上面的代码可保证不会使ERangeError异常被多次处理。假如颠倒两条响应语句的顺序,则ERangeError异常响应将永远没有被执行的机会。 

  由于异常在处理后即被清除,因而当希望对异常进行多次处理时就需要使用保留字raise来重引发一个当前异常。

  下面的代码同时使用了异常响应和异常保护。异常响应用于设置变量的值,异常保护用于释放资源。当异常响应结束时利用raise重引发一个当前异常。 

var

APointer: Pointer ;

AInt , ADiv: Integer;

begin

ADiv := 0;

GetMem ( APointer , 1024 );

try

try

AInt := 10 div ADiv ;

except

on EDivByZero do

begin

AInt := 0 ;

raise;

end;

end;

finally

FreeMem ( APointer , 1024 );

end;

end;

  上面一段代码体现了异常处理的嵌套。异常保护、异常响应可以单独嵌套也可以如上例所示的那样相互嵌套。 

12.3.5 自定义异常类的应用 

  利用Delphi的异常类机制我们可以定义自己的异常类来处理程序执行中的异常情况。同标准异常不同的是:这种异常情况并不是相对于系统的正常运行,而是应用程序的预设定状态。比如输入一个非法的口令、输入数据值超出设定范围、计算结果偏离预计值等等。

  使用自定义异常需要:

  1.自己定义一个异常对象类;

  2.自己引发一个异常。 

12.3.5.1 定义异常对象类 

  异常是对象,所以定义一类新的异常同定义一个新的对象类型并无太大区别。由于缺省异常处理只处理从Exception或Exception子类继承的对象,因而自定义异常类应该作为Exception或其它标准异常类的子类。这样,假如在一个模块中引发了一个新定义的异常,而这个模块并没有包含对应的异常响应,则缺省异常处理机制将响应该异常,显示一个包含异常类名称和错误信息的消息框。

  下面是一个异常类的定义: 

  type

EMyException = Class(Exception) ; 

12.3.5.2 自引发异常 

  引发一个异常,调用保留字raise,后边跟一个异常类的实例。

  假如定义: 

type

EPasswordInvalid = Class(Exception); 

则在程序中如下的语句将引发一个EPasswordInvalid异常: 

 If Password <> CorrectPasswordthen

raise EPasswordInvalid.Create('Incorrect Password entered');

  异常产生时把System库单元中定义的变量ErrorAddr的值置为应用程序产生异常处的地址。在你的异常处理过程中可以引用ErrorAddr的值。

  在自己引发一个异常时,同样可以为ErrorAddr分配一个值。

  为异常分配一个错误地址需要使用保留字at,使用格式如下: 

  raise EInstance at Address_Expession; 

-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
最新入库:
 
·实质、过程及意义——阿多尔诺“否定的辩证法”探微
·从Ontology的译名之争看哲学术语的翻译原则
·论马克思主义哲学经典的解释——解释学方法及其在马克
·中国哲学当前的核心与周边问题
·和合学与21世纪文化价值和科技
·中国文化的和合精神与21世纪
·宗教之间理当相互宽容
·上半个世纪的自由主义
·殷周至春秋时期神人关系之演进
·大学之道:构建以“三纲八目”为核心的道德修养体系
相关内容:
 
网友点评:
 
会员名称:
密码:匿名 ·注册·忘记密码?
评论内容:
(最多300个字符)
  查看评论
友情提醒:
 1.库中的资料大都来自互联网、网友上传、各类书籍,在录入的过程中难免会出现错误,恳请网
 友来信指正!
 2.如果网友在本库中未能找到所需要的材料,请登陆到我们的论坛《招考学习网》版块!
 3.考友想加入招考学习网的编辑部,请发信到XueXiWang#Gmail.com(#改为@)附带个人简历
 4.如需转载请注明出处及作者,谢谢合作!
 5.如果您有更好的建议或意见请EMAIL:XueXiWang#Gmail.com (#改为@)
 6.凡标题中有注有“[NO]”字样均不含答案且答案整理中.
 7.如本库中转载文章涉及版权等问题,请相关网站或作者在两周内发邮件通知(EMAIL:  XueXiWang#Gmail.com (#改为@))我们,我们接到通知后立即删除该文章及链接!
你问我答 更多>>