问题:Delphi 的RTTI机制浅探 ( 积分:100, 回复:21, 阅读:352 ) 分类:Object Pascal ( 版主:menxin, cAkk )
来自:savetime, 时间:2004-1-21 0:48:00, ID:2420610 Delphi 的RTTI机制浅探
savetime2k@yahoo 2004.1.20 savetime.delphi
bbs 目录
[显示:小字体 | 大
===========================================================================⊙ RTTI 简介
⊙ 类(class) 和 VMT 的关系
⊙ 类(class)、类的类(class of class)、类变量(class variable) 的关系 ⊙ TObject.ClassType 和 TObject.ClassInfo ⊙ is 和 as 运算符的原理 ⊙ TTypeInfo – RTTI 信息的结构 ⊙ 获取类(class)的属性(property)信息 ⊙ 获取方法(method)的类型信息
⊙ 获取有序类型(ordinal)、集合(set)类型的 RTTI 信息 ⊙ 获取其它数据类型的 RTTI 信息
===========================================================================
本文排版格式为:
正文由窗口自动换行;所有代码以 80 字符为边界;中英文字符以空格符分隔。
(作者保留对本文的所有权利,未经作者同意请勿在在任何公共媒体转载。)
正文
===========================================================================⊙ RTTI 简介
===========================================================================
RTTI(Run-Time Type Information) 翻译过来的名称是“运行期类型信息”,也就是说可以在运行期
数据类型或类(class)的信息。这个 RTTI 到底有什么用处,我现在也说不清楚。我是在阅读 Delp
续机制的代码中发现了很多 RTTI 的运用,只好先把 RTTI 学习一遍。下面是我的
学习笔记。如发现了错误请告诉我。谢谢!
Delphi 的 RTTI 主要分为类(class)的 RTTI 和一般数据类型的 RTTI,下面从类(class)开始。
===========================================================================⊙ 类(class) 和 VMT 的关系
===========================================================================
一个类(class),从编译器的角度来看就是一个指向 VMT 的指针(在后文用 VMTptr 表示)。在
VMTptr 的负地址方向存储了一些类信息的指针,这些指针的值和指针所指的内容在编译后就确
比如 VMTptr - 44 的内容是指向类名称(ClassName)的指针。不过一般不使用数值来访问这些类信而是通过 System.pas 中定义的以 vmt 开头的常量,如 vtmClassName、vmtParent 等来访问。
类的方法有两种:对象级别的方法和类级别的方法。两者的 Self 指针意义是不同的。在对象级别
法中 Self 指向对象地址空间,因此可以用它来访问对象的成员函数;在类级别的方法中 Self 指的 VMT,因此只能用它来访问 VMT 信息,而不能访问对象的成员字段。
===========================================================================⊙ 类(class)、类的类(class of class)、类变量(class variable) 的关系
===========================================================================
上面说到类(class) 就是 VMTptr。在
Delphi 中还可以用 class of 关键字定义类的类,并且可以使
的类定义类变量。从语法上理解这三者的关键并不难,把类当成普通的数据类型来考虑就可以了。译器级别上表现如何呢?
为了简化讨论,我们使用 TObject、TClass 和 TMyClass 来代表上面说的三种类型: type
TClass = class of TObject; var
TMyClass: TClass; MyObject: TObject; begin
TMyClass := TObject; MyObject := TObject.Create; MyObject := TClass.Create; MyObject := TMyClass.Create; end;
在上面的例子中,三个 TObject 对象都被成功地创建了。编译器的实现是:TObject 是一个 VMT
量。TClass 也是一个 VMTptr 常量,它的值就是 TObject。TMyClass 是一个 VMTptr 变量,它
值为 TObject。TOb