- 162 -
Program control
对Destructor来说,若布尔标志是False,则表明是使用inherited进行调用,此时,它就像一个普通的方法;若标志值是True,则表明是通过一个(对象)实例进行调用,此时,destructor在返回前释放实例(given by Self,实例通过Self给出)。
这个标志参数就像在其它所有参数之前声明。在register调用约定下,它通过DL寄存器传递;在pascal约定下,它在其它参数之前被压入栈;在cdecl、stdcall和safecall约定下,它在其它参数之后、在Self之前被压入栈。
因为DL寄存器指示constructor或destructor是否在调用栈的最外面(outermost),所以在退出之前你必须恢复DL的值,这样BeforeDestruction和AfterConstruction才能被正确调用。
Exit procedures(结束过程,非Exit过程)
结束过程使某些动作(比如更新文件和关闭文件)在程序结束之前被执行。ExitProc指针变量允许你‘安装’一个结束过程,它在程序结束时总是被执行:不管程序是正常结束,还是调用Halt,还是产生了运行时错误而退出。
注意:要对程序的退出采取行动时,推荐使用结束化部分(finalization section),而不是结束过程。结束过程只对执行文件、共享对象(Linux)或DLL(Windows)是可用的,包则必须使用结束化部分进行处理。所有结束过程在结束化部分(finalization section)之前被执行。
单元可以像程序一样安装结束过程。一个单元可在初始化代码中‘安装’结束过程,依靠它来关闭文件或执行清除任务。
当正确实现时,一个结束过程是结束过程链中的一部分。结束过程和安装过程的顺序相反,这样保证了一个单元的结束过程不会在另一个依赖它的单元之前被执行。要保证链的完整无缺,在把ExitProc指向自己的过程之前必须保存它的内容,而且,在你的结束过程中,第一个命令就是把ExitProc恢复为原来保存的值。
下面的代码演示了一个结束过程的实现结构:
var
ExitSave: Pointer;
procedure MyExit;
begin
ExitProc := ExitSave; // 总是先恢复原来的值
...
end;
begin
ExitSave := ExitProc;
ExitProc := @MyExit;
...
end.
在程序入口,代码先保存ExitProc中的内容到ExitSave,然后‘安装’MyExit过程。当作为结束过程的一部分被调用时,MyExit首先要做的事就是重新‘安装’以前的结束过程。
运行库(Delphi的运行库?)中的结束例程会一直调用结束过程,直到ExitProc变成nil。为避免无限制循环,在每个调用之前,ExitProc被设置为nil,所以,只有在当前的结束过程中给ExitProc赋一个地址,下一个结束过程才被调用。若在一个过程中发生了错误,它就不会再调用。
一个结束过程,通过检测ExitCode(整数)和ErrorAddr(指针)变量的值,可得知程序结束的原因。在正常结束的情况下,ExitCode值为0,ErrorAddr为nil;当通过调用Halt结束时,ExitCode值为传给Halt的参数,ErrorAddr为nil;若发生运行时错误,ExitCode包含错误码,ErrorAddr包含无效指令的地址。
- 163 -
Program control
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-23665-122.html
稻谷收购价降了
过期商品支接罚50000
芝麻糊还有肉末