VCL分析(一) (100分)

  • 主题发起人 主题发起人 timerri
  • 开始时间 开始时间
T

timerri

Unregistered / Unconfirmed
GUEST, unregistred user!
最近看到烂书充斥市场,于是很想写本书,初步的想法是想到哪里就写到哪里,最后再整理出来。于是就有了下面这些东西
欢迎大家指正,如果有什么需要增加的部分或疑难的问题,请大家也一并提出来。
从TObject谈起
可能从我们第一次接触DELPHI的时候我们就碰到了对象和类的概念,在后来的学习过程中又不可避免的继续与类和对象打着
交道。我们现在就从所有VCL类的基类Tobject谈起。
Tobject究竟实现了什么?他凭什么做所有类的基类?看来只有看代码才能解决问题。来,让我们转到system.pas来看一看。
TObject = class
constructor Create;//构造函数,空的
procedure Free;//析构函数,也是空的
class function InitInstance(Instance: Pointer): TObject;//初始化实例,并装载接口
procedure CleanupInstance;//清空实例
function ClassType: TClass;//类类型
class function ClassName: ShortString;//类名
class function ClassNameIs(const Name: string): Boolean;//类名是否是name
class function ClassParent: TClass;//父类
class function ClassInfo: Pointer;//类信息
class function InstanceSize: Longint;//实例大小
class function InheritsFrom(AClass: TClass): Boolean;//是否从aclass继承
class function MethodAddress(const Name: ShortString): Pointer;//按名称找方法地址
class function MethodName(Address: Pointer): ShortString;//按地址找方法名
function FieldAddress(const Name: ShortString): Pointer;
function GetInterface(const IID: TGUID;
out Obj): Boolean;
class function GetInterfaceEntry(const IID: TGUID): PInterfaceEntry;
class function GetInterfaceTable: PInterfaceTable;
function SafeCallException(ExceptObject: TObject;
ExceptAddr: Pointer): HResult;
virtual;
procedure AfterConstruction;
virtual;
procedure BeforeDestruction;
virtual;
procedure Dispatch(var Message);
virtual;
procedure DefaultHandler(var Message);
virtual;
class function NewInstance: TObject;
virtual;
procedure FreeInstance;
virtual;
destructor Destroy;
virtual;
end;
以上是Tobject的声明。我们先大致看看能得到什么!Create, Free,Destroy我们就不去说它了,构造函数和析构函数的概
念好像每本面向对象的书里都有。
可是ClassType ClassName ClassNameIs ClassParent ClassInfo InheritsFrom InstanceSize,这些东西是干什么的?听过
RTTI(执行期类型识别)的朋友可能会有点想法了。对,利用他们就可以得到RTTI的一些信息,Tobject作为所有类的基类,把
这种得到RTTI信息的能力带给了所有的类。没听过RTTI的朋友可能现在就有点昏,没关系,我们现在就来讲一下。在DELPHI中
,每个类都有一个VMT(虚拟方法表),每个对象的起始四个字节就保存着对应VMT的32位指针。下面是HELP里抄的一段,好好看
看VMT里到底有些什么。
Offset Type Description
-76 Pointer pointer to virtual method table (or nil)
-72 Pointer pointer to interface table (or nil)
-68 Pointer pointer to Automation information table (or nil)
-64 Pointer pointer to instance initialization table (or nil)
-60 Pointer pointer to type information table (or nil)
-56 Pointer pointer to field definition table (or nil)
-52 Pointer pointer to method definition table (or nil)
-48 Pointer pointer to dynamic method table (or nil)
-44 Pointer pointer to short string containing class name
-40 Cardinal instance size in bytes
-36 Pointer pointer to a pointer to ancestor class (or nil)
-32 Pointer pointer to entry point of SafecallException method (or nil)
-28 Pointer entry point of AfterConstruction method
-24 Pointer entry point of BeforeDestruction method
-20 Pointer entry point of Dispatch method
-16 Pointer entry point of DefaultHandler method
-12 Pointer entry point of NewInstance method
-8 Pointer entry point of FreeInstance method
-4 Pointer entry point of Destroy destructor
0 Pointer entry point of first user-defined virtual method
4 Pointer entry point of second user-defined virtual method
真是一堆好东西。类的主要信息就包含在这里了,它才是真正RTTI的主角,ClassType ClassName ClassNameIs
ClassParent ClassInfo InheritsFrom InstanceSize这堆函数不过是从VMT中读取出对应的参数罢了。
你不会要问我RTTI有什么用吧!我昏!试想一下,一个函数传了个对象给你,你又不能确定它究竟是个什么
对象,就如VCL中大量存在的(Sender: Tobject),那么用sender.ClassName就没错了,看看是否知道了传过
来的是什么东西?
CleanupInstance FreeInstance InitInstance NewInstance,这些东西又是干什么的?看名字大概就能看出
来,这是对象创建和释放时的操作。所有的构造函数(就是以constructor打头的)都自动的运行Newinstance,
Newinstance为对象实例分配内存并返回对象指针。在Newinstance中调用了InitInstance来进行对象的初始化操作。
在InitInstance中清零了对象实例并且赋值了接口地址。CleanupInstance FreeInstance就是负责对象实例的释放。
请注意,如果需要创建一个非默认内存大小的对象的话,可以重载NewInstance,但是同时也必须重载FreeInstance
来释放内存,重载的NewInstance也必须调用InitInstance而不是用inherited。
还剩下几个函数我这里就不一一讲解了,大家可以自己看看源代码。
再来谈谈面向对象
做DELPHI程序,我们大部分时间都在和对象打交道,但是我们是否真的明白了面向对象的所有?恐怕不见得
,做个简单的测试,Tclass=class of Tobject;
这里Tclass是个什么东西?如果你说不清楚,那么就老老实实往下看。
面向对象是通过为数据和代码建立分块的内存区域来提供对程序模块化的程序设计方法。与C++有些不同,
DELPHI中的对象包含数据(fields)、方法(methods)和属性(properties),而C++中只包含数据(比较奇怪,c++中叫property)
和方法,DELPHI中的属性更有利于面向对象的代码封装,而且更适于可视化编程。属性其实是一个对外接口,一般和一个数据相关联,
他决定了这个数据怎样被读和怎样被修改。
DELPHI中对象的封装也是靠“类”实现的。类其实是对象的抽象、也是对象的模板,对象是类的实例。在DELPHI中,
每个对象都有一份自己数据部分的内存拷贝,但是同类的对象共用相同的代码部分。对象的创建由类来负责,也就是
constructor声明的方法来创建。对象在实现上其实是个指针,他指向自己的实体部分,但我们用他的时候不用把它当作指针,
当我们使用了^时他才确实当作指针使用。现在来看看我们的问题,什么是Tclass?千万不要被前面那个T迷惑了让你认为它是一个类,
其实它是一个类型,单独看Tclass看不出什么来,当我们用它来声明变量后你就会看出他的作用来,那么我们就声明aobj:Tclass看看
有什么效果。这时候,就可以把任何类赋值给aobj,如aobj:=button1.classtype;这样aobj的值就是Tbutton。如果再要创建这样的对象,
就用aobj.create就可以得到另一个Tbutton的实例。而且aobj还可以当作参数传递,这样我们需要动态创建对象而又不能确定对象类型的
时候,就不至于那么一筹莫展了。
 
换行!高手!我看得很累![:(]
 
[:D]改了,我拿word写的,改起来好麻烦。
这个换行应该是yysun的技术问题,当初我做论坛的时候从来都能实现自动换行的
 
分辨率大一点也就可以了。
 
各位没有任何意见么?
 
大哥不要着急,正在拜读!
 
赫赫,光说这个没什么用,要说清楚borland 为什么这么写TObject,意图何在
有什么优点,为什么很多方法声明为class 方法。关于RTTI的用途,怎么用,使用RTTI的好处,嘿嘿光一个RTTI要想
解释清楚,就可以写200-300页的。TClass的标准说法应该是一个元类吧。
在说说VMT的方法,再写一个函数可以根据VMT获得对象的方法总数等等等等。
另外如何利用NewInstance实现一个Singleton模式
再有TPersistent和TObject的区别,还有如何实现从TObject的继承的类也支持RTTI
等等等等。对象的可持续性是如何实现的,
另外,MethodAddress可是有很妙的用途的说,你清楚吗?
.....
总而言之,想写一个VCL深入浅出,没有1000页以上的文字是说不清楚的
 
是呀,我也想写详细点,但是怕我书写出来后DELPHI已经过时了....
hubdog兄整理的宝典确实是好东西,但是就是觉得太散了点。看起来有点费力
hubdog胸有否兴趣也写一点东西出来?就把底层一点的东西写清楚我们就获益匪浅了
 
等明年有空了,看能不能写一本vcl架构分析
 
好东西好东西,有东东学还有分拿真不错
 
看完了,真的不错,什么时候出二啊!
 
我知道什么是面向對象
我想知道為什么要面向對象
我更想知道如何進行軟件(而不是VCL)的面向對象開發
我最想知道為什么Borland 的 delphi可以有這樣的擴展性﹐
而我的程序改一點點都要修改半天.
VMT(虚拟方法表)里面那一個字節用來干什么對我這種
數據庫開發人員來說一點用都沒有
 
好!!最好给我们多讲点!!让我洗洗脑!
 
do not know good or bad
 
难得有人从底层讲起的,不过感觉说的不透...
 
TObject的Create为空,这可以理解的.
为什么它的Free也为空的呢?
 
后退
顶部