关键字dynamic的用法(50分)

  • 主题发起人 主题发起人 scx2002112
  • 开始时间 开始时间
S

scx2002112

Unregistered / Unconfirmed
GUEST, unregistred user!
以及和virtual 的区别
 
Virtual versus dynamic(比较虚方法和动态方法)
虚方法和动态方法在语义上是相同的,唯一的不同是在运行时决定方法调用的实现方式上,虚方法在速度上进行了优化,而动态方法在代码大小上做了优化。
通常情况下,虚方法是实现多态行为的最有效的实现方式。当基类声明了大量的要被许多派生类继承的(可覆盖的)方法、但只是偶尔才覆盖时,动态方法还是比较有用的。
 
有修饰语Virtual称为虚方法,有修饰语Dynamic称为动态方法。两者从结果上看没有太多的区别,但是在内部实现上,虚方法速度较快,但内存耗用较大,而动态方法内存耗用较小,但速度较慢。
 
当代码要调用一个指定的虚方法时,编译器并不知它的地址在哪,所以它需要利用创建一个虚拟方法表(VMT)来得到运行时的地址
所有的虚方法都要通过VMT来调度,而且VMT中除了自己定义的虚方法外还包含它的祖先的所有的虚方法,因此相对来讲它占用的内存要多一些,但速度要快一些

同样动态方法也是通过一个表来调度,但是这个表是由编译器为这个动方法指定的一个唯一的代表地址的数字和它的地址构成的,叫DMT,在DMT表中仅有它声明的动方法,而且这个方法需要祖先的DMT访问其它的动方法,所以它与虚方法比较占用的资源要少,但因为它要到祖先对象中找动方法,所以速度上要慢一些。
 
借zxdcj兄的帖子说一点,dynamic 有助于节约VMT的资源,看一看VCL庞大的体系结构,全部使用Virtual的话,到了第四层、五层,控件的的VMT恐怕很大,borland的工程师没有这样做,在父类中为子类可能的关键方法声明为virtual,其他的则声明为dynamic,很好的兼顾了效率和资源。推荐读李维Inside VCL。

 
berock兄说的极是
 
虚方法使用virtual限定符,动态方法使用dynamic限定符,无论是virtual限定符还是dynamic限定符均表示在基类中声明了一个虚方法,其目的是为了派生类能够覆盖该方法,实现多态.这两个限定符的语义是相同的,惟一不同的是,它们产的实现方法和调用方法,这涉及到Delphi的编译机制.
Delphi的编译器会自动维护用于添加虚方法的虚方法表(VMT)和用于添加动态方法的动态方法表(DMT).
虚方法表存放的是类及其基灶声明的所有虚方法的指针.每一个类都具有一个惟一的VMT,每一个类或其祖类的虚方法在VMT中都有一个入口.无论一个类是否有自己定义的虚方法,只要它继承了祖先类的虚方法,它也会有自己的VMT,列出它继承的所有虚方法.因为每一个类都有一个自己的VMT,Delphi就可以使用VMT来识别一个类,实际上,一个类引用就是指向类的VMT的指针,调用classtype方法则返回指向VMT的指针.
由于基类和派生类的VMT之间过强的关联性,因此派生类继承了祖先类的虚方法,也就是说派生类的VMT的前面一部分必须与基类相同.而当基类和派生类不在同一个DLL或EXE中的时候,这个要求是很难满足的.基类一旦改变,派生类如果不重新编译,就将导致错误.另外,如果类的层次很深,比如要建一个有数百个类的大型框架,此时VMT将会因不断继承的虚方法而变得非常庞大,导致效率不高.
为了解决这个问题,Delphi提供了一个DMT的机制.每一个类的DMT中只维护部分的动态方法,也就是说DMT仅列出了该类所声明的动态方法,它并不包括从祖先类那里继承来的方法.
虽然dynamic方法解决了virtual的方法问题,但是也付出了不小的代价:时间效率和可读性,因此也决定了该方案的应用面一广.大多数情况下使用virtual方法要比dynamic方法快,占用内存少.
 
谢谢大家
 
后退
顶部