,不 会执行派生类的Destroy
多态的目的
? 所有的对象都可被塑造为相同的类型,响 应相同的
消息 ? 代码简单,容易理解 ? 接口重用,程序有好的扩展性
VMT/DMT
? 派生类对象所占的内存空间必定大于或等 于基类对象所占的内存空间,将基类类型 的指针指向派生类类型的对象时,在指针 的可视范围中的内存必定是可用的,这一 部分内存空间必定是属于对象的,所以这 种赋值行为是合法的、安全的,并且得到 编译器认可的。
对象实体
指向VMT的指针
FMember1 FMember2 FMember3
VMT
基类
VMT
? VMT(Virtual Method Table,虚方法表), 这个表中存放了基类的所有虚方法的入口 地址。在Object Pascal中,所有类实例都会 有这么一个指向VMT的指针。如果没有在类 中声明虚方法,则该指针为nil。 ? 没有被派生类覆盖的方法,编译器会将基 类的该方法的实现的入口地址填入派生类 的VMT中 ? 指针指向的是用户编写的第一个虚方法的 地址
DMT
? DMT(动态方法表)
– Object Pascal所独有的 – dynamic关键字 – 引入原因:在VMT中,派生类的虚方法表完全 继承了基类的虚方法表,只是将被覆盖了的虚 方法的地址改变了。基类和每个派生类都有一 份自己的虚方法表。随着类层次的扩展,虚方 法表将耗费非常大的内存空间。
DMT和VMT的区别:
? 对于派生类没有覆盖的方法,这些方法的 入口地址不会出现在DMT中,编译器要通 过基类的信息来寻找它们的入口地址。 ? DMT中对基类的动态方法的寻址不是直接 进行的,因此dynamic方法的寻址比virtual 方法要慢许多。
谢 谢 大 家!