12.2 类构造函数(和析构函数)
类构造函数负责初始化与类相关的数据,作用类似于类的初始化器,因为它们实际上并不创建任何东西。类构造函数与标准实例构造函数无关:它只是用于在使用类之前初始化类本身的代码。例如,类构造函数可以为类数据设置初始值,加载配置或支持文件等。
在Object Pascal中,类构造函数可以替代Unit单元initialization代码。如果两者都存在(在一个Unit中),类构造函数将首先执行,然后执行Unite单元的initialization代码。反之,您定义的类析构函数将在Unite单元的finalization代码之后执行。
然而,一个显著的不同是,如果将Unit 编译到程序中,initialization代码总是会被执行,但只有在实际使用类时,类构造函数和析构函数才会被链接。这意味着使用类构造函数比使用初始化代码更有利于链接器。
注解 换句话说,对于类的构造函数和析构函数,如果类型没有被链接,初始化代码就不是程序的一部分,也不会被执行。 在传统情况下,情况恰恰相反,初始化代码甚至可能导致链接器引入某些类代码,即使这些代码实际上从未在其他地方使用过。 实际上,这是与手势框架一起引入的,如果不使用,大量代码就不会编译到可执行文件中。
在编码方面,您可以编写以下内容(请参见ClassCtor示例):
type
TTestClass = class
public
class var
StartTime: TDateTime;
EndTime: TDateTime;
public
class constructor Create;
class destructor Destroy;
end;
该类具有两个类数据字段,由类构造函数初始化,并由类析构函数修改,而Unite单元的initialization和finalization部分使用了这些数据字段:
class constructor TTestClass.Create;
begin
StartTime := Now;
end;
class destructor TTestClass.Destroy;
begin
EndTime := Now;
end;
initialization
ShowMessage(TimeToStr(TTestClass.StartTime));
finalization
ShowMessage(TimeToStr(TTestClass.EndTime));
发生的情况是,启动序列按预期工作,类数据已经可用,因此您可以显示信息。相反,当关闭时,ShowMessage调用在类析构函数分配值之前执行。
请注意,可以为类构造函数和析构函数指定任何名称,尽管Create和Destroy可能是非常好的默认值。但是,您不能定义多个类构造函数或析构函数。如果尝试这样做,编译器将发出类似于以下的错误:
[DCC Error] ClassCtorMainForm.pas(34): E2359 Multiple class constructors in class TTestClass: Create and Foo