对象异常类
所谓对象异常是指非部件的对象引发的异常 Delphi定义的对象异常包括流异常 打印异常 图形异常 字符串链表异常等
流异常类
流异常类包括EStreamError EFCreateError EFOpenError EFilerError EReadError EWriteError EClassNotFound 它们的结构关系如下
EStreamError
| EFCreateError
| EFOpenError
| EFilerError
| EReadError
| EWriteError
| EClassNotFound
流异常在Classes库单元中定义
流异常引发的原因如表
表 流异常类及其产生原因
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
异常类 引发原因
─────────────────────────────────
EStreamError 利用LoadFromStream方法读一个流发生错误
EFCreateError 创建文件时发生错误
EFOpenError 打开文件时发生错误
EFilerError 试图再次登录一个存在的对象
EReadError ReadBuffer方法不能读取特定数目的字节
EWriteError WriteBuffer方法不能写特定数目的字节
EClassNotFound 窗口上的部件被从窗口的类型定义中删除
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
打印异常类
打印异常类EPrinter当打印发生错误时引发 它在printers库单元中定义 例如你的应用程序试图向一个不存在的打印机打印或由于某种原因打悄中印工作无法送到打印机时 就会产生一个打印异常
图形异常类
图形异常类定义在Graphic 库单元中 包括EInvalidGraphic和EInvalidGraphicOperation两类
EInvalidGraphic当应用程序试图从一个并不包含合法的位图 图标 元文件或用户自定义图形类型的文件中装入图形时引发 例如下面的代码
Image Picture LoadFromFile( Readme txt )
由于Readme txt并不包含一个合法的图形 因而将引发一个EInvalidGraphic异常
闭运贺 EInvalidGraphicOperation当试图对一个图形进行非法 *** 作时引发 例如试图改变一个图标的大小
var
AnIcon: TIcon
begin
AnIcon := TIcon Create
AnIcon LoadFromFile( C:\WINDOWS\DIRECTRY ICO )
AnIcon Width := { 引发一个图形异常 }
…
字符串链表异常
字符串链表异常EStringListError EListError在用户对字符串链表进行非法 *** 作时引发 由于许多部件(如TListBox TMemo TTabSet …)都有一个TStrings类的重要属性 因而字符串链表异常在部件 *** 作编程中非常有用
EStringListError异常一般在字符串链表越界时产生 例如对如下初始化的列表框轿派
ListBox Items Add( First item )
ListBox Items Add( Second item )
ListBox Items Add( Third item )
则以下 *** 作都会引起EStringListError异常
ListBox Item[ ] := Not Exist
str := ListBox Item [ ]
EListError异常一般在如下两种情况下引发
当字符串链表的Duplicates属性设置为dupError时 应用程序试图加入一个重复的字符串
试图往一个排序的字符串链表中插入一个字符串
部件异常类
通用部件异常类
通用部件异常类常用的有三个 EInvalidOperation EComponentError EOutOfResource 其中EInvalidOperation EOutOfResource在Controls单元中定义 EComponentError在Classes单元中定义
非法 *** 作异常 EInvalidOperation
EInvalidOperation 引发的原因可能有
● 应用程序试图对一个Parent属性为nil的部件进行一些需要Windows句柄的 *** 作
● 试图对一个窗口进行拖放 *** 作
● *** 作违反了部件属性间内置的相互关系等
例如 ScrollBar Gauge等部件要求Max属性大于等于Min属性 因而下面的语句
ScrollBar Max := ScrollBar Min
将引发一个EInvalidOperation异常
部件异常EComponentError
引发该异常的原因可能有
● 在Register过程之外试图登录一个部件(常用于自定义部件开发中)
● 应用程序在运行中改变了一个部件的名称并使该部件与另一个部件重名
● 一个部件的名称改变为一个Object Pascal非法的标识符
● 动态生成一个部件与已存在的另一部件重名
资源耗尽异常EOutOfResource
当应用程序试图创建一个Windows句柄而Windows 却没有多余的句柄分配时引发该异常
专用部件异常类
许多部件都定义了相应的部件异常类 但并不是有关部件的任何错误都会引发相应的异常类 许多情况下它们将引发一个运行时间异常或对象异常
下面列出几个典型的部件异常类
EMenuError
非法的菜单 *** 作 例如试图删除一个不存在的菜单项 这一异常类在Menus库单元中定义
EInvalidGridOpertion
非法的网格 *** 作 比如试图引用一个不存在的网格单元 这一异常类在Grids库单元中定义
EDDEError
DDE异常 比如应用程序找不到特定的服务器或会话 或者一个联接意外中止 这一异常类在DDEMan库单元中定义
EDatabaseError EReportError
数据库异常(EDatabaseError)和报表异常(EReportError) 在进行数据库和报表 *** 作出现错误时引发 有关数据库的问题请读者参阅本书第二编
小结
在这一节中重点介绍了Delphi提供的异常类体系 我们力求给读者一个清晰 全面的印象 使读者能在自己的程序开发中实际使用它们 为便于理解我们也提供了一些简单的说明性示例 虽然在具体的使用中读者还可能会碰到许多问题 但意识到应该用异常类来增强程序的健壮性却是程序设计水平走上新台阶的标志
异常保护
确保回收分配的资源是程序健壮性的一个关键 但缺省情况下异常发生时程序会在出错点自动退出当前模块 因此需要一种特殊的机制来确保即使在异常发生的情况下释放资源的语句仍能被执行 而Delphi的异常处理正提供了这种机制
需要保护的资源
一般说来需要保护的资源包括
● 文件
● 内存
● Windows资源
● 对象
比如下面一段程序就会造成 K内存资源的丢失
var
APointer : Pointer
AInt ADiv: Integer
begin
ADiv :=
GetMem ( APointer )
AInt := div ADiv
FreeMem ( Apointer )
end
由于程序从异常发生点退出从而FreeMem永远没有执行的机会
lishixinzhi/Article/program/Delphi/201311/25193
EIntOverFlow异常类在Integer Word Longint三种整数类型越界时引发 如
var
I : Integer
a b c : Word
begin
a :=
b :=
c :=
for I := to do
begin
c := a*b*c
end
end
引发一个EIntOverFlow异常
EIntOverFlow异常类只有在编译选择框Option|Project|Over_Flow_Check Option选中时才产生 当关闭溢出检查 则溢出后变量保留该类整数的最大范围值
整数类型的范围如下表
表 整数类型的范围
━━━━━━━━━━━━━━━━━━━━━━━━老搏━━━
类型 范围 格式
───────────────────────────
Shortint 有符号 位
Integer 有符号 位
Longint 有符号 位
Byte 无侍弯祥符号 位
Word 无符号 位
━━━━━━━━━━━━━━━━━━━━━━━━━━━
浮点异常
浮点异常是在进行实数 *** 作时产生的 它们都从一个EMathError类派生 但与整数异常相同 程序运行中引发的总是它的子类EInvalidOp EZeroDivide EOverFlow EUnderFlow
表 浮点异常类及其引发原因
━━━━━━━━━━━━━━━━━━━━━━━━
异常类 引发原因
────────────────────────
EInvalidOp 处理器碰到一个未定义的指令
EZeroDivide 试图被零除
EOverFlow 浮点上溢
EUnderFlow 浮点下溢
━━━━━━━━━━━━━━━━━━━━━━━━
EInvalidOp最常见的引发原因是没有协处理器的机器遇到一个协处理器指令 由于在缺省情况下Delphi总是把浮点运算编译为协处理器指令 因而在 以下微机上常常会碰到这个错误 此时只需要在单元的接口部分设置全局编译指示{$N } 选择利用运行时间库进行浮点运算 问题就可以解决了
各种类型的浮点数(Real Single Double Extended)越界引起同样的溢出异常 这同整数异常类是不同的
类型匹配异常
类型匹配异常EInvalidCast当试图用As *** 作符把一个对象与另一类对象匹配失败后引发
类型转换异常
类型转换异常EConvertError当试图用转换函数把数据从一种形式转换为另一种形式时引发 特别是当把一个字符串转换为数值时引发 下面程序中的两条执行语句都将引发一个EConvertError异常
var
rl : Real
int: Integer
begin
rl := StrToFloat( $ )
int := StrToInt( )
end
要注意并不是所有的类型转换函数都会引发EConvertError异常 比如函数Val当它无法完成字符串到数值的转换时只把错误代码返回 利用这一点我们在( )节中实现了输入的类型和范围检查
硬件异常
硬件异常发生的情况有两种 或者是处理器检测到一个它不能处理的错误 或者是程序产生一个中断试图中止程序的执行 硬件异常不能编译进动态链接库(DLLs)中 而只能在标准的应用中使用
硬件异常都是EProcessor异常闹册类的子类 但运行时间并不会引发一个EProcessor 异常
表 硬件异常类及其产生原因
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
异常类 引发原因
─────────────────────────────────
Efault 基本异常类 是其它异常类的父类
EGPFault 一般保护错 通常由一个未 初始化的指针或对象引起
EStackFault 非法访问处理器的栈段
EPageFault Windows内存管理器不能正确使用交换文件
EInvalidOpCode 处理器碰到一个未定义的指令 这通常意味着处理器
试图去 *** 作非法数据或未初始化的内存
EBreakPoint 应用程序产生一个断点中断
ESingleStep 应用程序产生一个单步中断
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
EFault EGPFault 往往意味着致命的错误 而EBreakPoint ESingleStep被Delphi IDE的内置调试器处理 事实上前边的五种硬件异常的响应和处理对开发者来说都是十分棘手的问题
lishixinzhi/Article/program/Delphi/201311/25192
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)