VCL的诞生和设计原理(摘抄inside vcl)

VCL的诞生和设计原理
从无到有--?VCL对象生命的成型

基本的对象管理服务至少应该包含下面的服务:
l 对象的创建和初始化
l 对象方法的分配
l 对象的消灭

Object Pascal 的对象模型
使用Object pascal定义的Tobject类非常简单,只要如下两行代码就可以
Tobject =class
End;

这虽然时合法的类定义,但是实际用处不大,因为在创建类对象时必须为对象分配内存并且进行对象初始化之后才能正确的使用对象.
因此一般的类都会定义对象的构造函数(constructor或者ctor),而构造函数的目的就是为对象分配内存及进行对象初始化工作.由于对象分配了内存,因此当对象生命结束之后当然需要释放分配的内存以及进行初始化反向的工作,如此在能够归还系统资源,所以类也会定义析构函数(destructor 或者 dtor).因此最基础的类通常会定义成如下形式:
Tobject = class
  Constructor Create;
  Destructor Destroy; virtual;
End;

其中析构函数Destroy声明为virtual方法时因为在Tobject的派生类中可能会分配额外的资源,因此派生类可以改写(override)Tobject的析构函数,当派生类对象释放时,先释放他自己分配的资源,在调用Tobject的析构函数来释放Tobject为对象分配的资源.如果Tobject的析构函数不声明成虚拟方法,那么派生类的析构函数便会覆盖Tobject的析构函数,如此一来,只有派生类分配的内存会被释放,由Tobject为对象分配的资源则可能没有释放,这就造成了内存泄漏(leak)问题.

定义这样一个类:
TMyObject = class(Tobject)
  Destructor Destory ; override;
End;



Destructor TMyObject.Destory;
Begin
  //释放TmyObject分配的内存;
  inherited Destory;//调用父类的Destory;
End;

当我们使用如下程序代码创建TmyObject 时,发生了什么?
Obj := TMyObject.Create;
Object Pascal的对象模型在这行程序代码后进行了很多的工作,包括分配内存,设定字段变量数据结构,设定执行框架等工作,因此上面的程序可分解成如下的程序代码:
TMyObject.AllocateMemory;
TMyObject.InitializeSpecialFields;
Obj:= TMyObject.SetupExecFrame;

创建对象的第一步是分配内存,Object Pascal会使用内建的内存管理器为对象分配内存:
PMemoryManager = ^TMemoryManager;
TMemoryManager = record
  GetMem:function(Size:Integer):Pointer;
  FreeMem:function(p:Pointer):Integer;
  ReallocMem :function(P:pointer; Size:Integer):Pointer;
End;

虽然Object Pascal使用了默认的内存管理器,但是Object Pascal对象模型的设计似乎是允许切换内存管理器的.
在分配了对象的原始内存之后,Object Pascal的对象模型会先初始化所有的内存内容为0.
FillChar(Instance^ ,InstanceSize, 0);
然后对类中声明的特别字段进行初始化工作,如对于接口变量必须设定引用记数值为0,对于动态数组则必须初始化内存区块.
下面的TMyObject声明了Variant类型的字段变量vDate,那么Object Pascal的对象模式会对 vDate进行特别的初始化工作,至于GetHashValue虚拟方法则会进入VMT(Virtual Method Table)之中.
TMyObject =class(TObject)
Private
  VDate :Variant;
Public
  Function GetHashValue:Integer; virtual;
  Destructor Destory;override;
End;

posted on 2004-06-15 17:40  khan  阅读(956)  评论(1编辑  收藏  举报

导航