Delphi中虚拟方法表和动态方法表

Delphi中所有类都直接或者间接派生于TObject,一个TObject的实例:Object(对象)实际上是一个4字节的指针。该指针指向对象的实际数据区(Object Data)。对象的数据区划分很多的小区域,这些区域分为两部分:

(1)前4个字节存放一个指针,该指针指向另一个地址区域。

(2)其余小区域分别存放对象的各种数据成员。

   前四个字节字节的指针指向另一地址区域即“虚拟方法表(virtual method table,VMT)”,虚拟方法表又划分很多个大小为4字节的小区域,每个区域存放一个指针,每个指针对应一个虚拟方法的入口地址;其余小区域存放字段、属性值和所有的非虚方法的入口地址。由此可见废墟方法的存取相对简单,而虚方法的寻址与调用要复杂的多。

 

   1、 虚拟方法表结构

   如下图所示,一个对象指针指向一个对象数据域,对象数据域的前四个字节存放一个指针,该指针指向虚拟方法表。

 

VMT结构图

      

   2、VMT的产生 

   参照虚拟方法结构图,VMT表的负偏移区(-76~0)是基础信息,存储基础性数据(如实例大小、接口表、运行时类型信息表、字段表、方法表、类名和父类虚拟方法表等)的指针和多有的基础性虚拟方法的指针,而不全是指针列表,这个区域主要来帮助实现对象的构造与析构、运行是类型信息存取、字段和方法解析等,大小固定;正偏移区是用户定义的虚拟方法所在区域,每四个字节一个用户定义的虚拟方法指针。这些虚拟方法不仅指在本类定义的,还包括从Tobject一直到本类的所有中间类定义的虚拟方法。

    

    3、虚拟方法与动态方法比较

 

     实际应用中虚方法常见两类:虚拟方法(Virtual)和动态方法(Dyniamic),由上知Virtual方法被全部列入VMT的正偏移区,当一个对象请求调用Virtual方法时,可以在类的VMT中直接寻址,然后调用,除非调用一个Dynamic方法;一个动态方法表(DMT)来存储动态方法的入口地址,这是虚拟方法和动态方法调用的一个重大区别,而DMT又依赖于VMT来实现。DMT是一系列的指针列表,和VMT正偏移类似,存放了本类定义的和从父类继承并覆盖后的动态方法的入口地址。

 

    虚拟方法和动态方法相比,使用动态方法可以节省内存,因为它不存放未曾覆盖的虚方法指针,而且调用一个虚方法和调用在DMT中存放了入口地址的动态方法相比,速度没有显著差异。而如果使用虚拟方法,即使子类没有覆盖父类虚拟方法,子类中和父类也都会存放虚拟方法的入口地址。 

转载:http://blog.csdn.net/h_sure/article/details/4013566


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DELPHI方法的类型及其覆盖、重载 1、静态方法方法的缺省类型,对它就像对通常的过程和函数那样调用,编译器知道这些方法的地址,所以调用一个静态方法时它能把运行信息静态地链接进可执行文件,所以,静态方法速度最快,但它们却不能被覆盖来支持多态性。 2、虚拟方法和静态方法的调用方式相同。由于虚拟方法能被覆盖,在代码调用一个指定的虚拟方法时编译器并不知道它的地址,因此,编译器通过建立虚拟方法(VMT)来查找在运行时的函数地址。所有的虚拟方法在运行时通过VMT来高度,一个对象的VMT除了自己定义的虚拟方法外,还有它的祚的所有的虚拟方法,因此虚拟方法动态方法用的内存要多,但它执行得比较快。 3、动态方法虚拟方法基本相似,只是它们的高度系统不同。编译器为每一个动态方法指定一个独一无二的数字,用这个数字和动态方法的地址构造一个动态方法(DMT)。不像VMT,在DMT仅有它声明的动态方法,并且这个方法需要祖先的DMT来访问它蓁的动态方法。正因为这样动态方法虚拟方法用的内存要少,但执行起来罗慢,因为有可能要到祚对象的DMT查找动态法。 4、OP通过覆盖使一方法在不同的派生类间现出不同的行为。OP能被覆盖的方法是在声明时被标识为virtual或dynamic的方法。为了覆盖一个方法,在派生类的声明用override代替virtual或dynamic。用了override后,编译器就会用新的方法替换VMT原先的方法,而原先的方法也还存在,而如果用override再次声明一个静态方法,则是真正的覆盖,是用新的方法完全替换在祖先类的同明方法。 5、方法重载的意义:比如说,你要写一个求两数商的函数(当然只是个比喻),你希望这个函数可以处理所有的数值类型,但PASCAL的运算对类型实行严格检查,你不得不用不同的程序来运算不同类型的数值,这样你就必须为每一种类型写一个同样功能的函数,并使用不同的函数名,坏处我想你是知道的。而重载却可以解决这个问题,同样的函数名,编译器可以用不同的形参类型决定调用哪个函数。Top dynamic和virtual的不同之处 delphi动态虚拟覆盖重载重定义的区别 (www.ip8000.com www.sql8.net)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值