【问题标题】:What is the difference between dynamic and virtual methods?动态方法和虚拟方法有什么区别?
【发布时间】:2013-03-14 17:56:57
【问题描述】:

动态方法如何改进代码大小?
代码大小是什么意思???意思是program.exe文件大小??

根据手册:

一般来说,虚方法是最有效的实现方式 多态行为。动态方法在基类时很有用 声明了许多被许多人继承的可重写方法 应用程序中的后代类,但只是偶尔 被覆盖。

当只有一个继承类覆盖该方法时,如果我使用动态而不是虚拟,我将获得什么,因为手册还说:

虚拟方法优化速度,而动态方法优化代码大小。

【问题讨论】:

  • 这两个引号告诉你你需要知道什么。在我看来,底线是始终使用虚拟。
  • @DavidHeffernan 已编辑帖子!

标签: delphi


【解决方案1】:

虚拟方法是通过虚拟方法表 (VMT) 实现的。每个班级有一个 VMT。 VMT 为类中的每个虚拟方法包含一个条目。而那个入口就是方法的地址。

这允许非常有效的调用。您只需获取位于与Self 的固定偏移量的 VMT 的地址。然后通过索引查找方法指针并调用方法。

这意味着如果你有一个包含很多虚拟方法的类,并且你派生了一个子类,你将创建一个包含所有虚拟方法的全新 VMT。如果您没有覆盖其中的许多,那么您会发现 VMT 有很多重叠。

这在 16 位时代很重要。 VMT 可能会占用可执行映像中的大量空间(这就是代码大小的含义),并且您可能会用完 VMT 的空间。因此引入了动态方法。与 VMT 类似的是动态方法表 DMT。这是以不同的方式实现的,以避免在方法未被覆盖时重复。缺点是调用动态方法更昂贵。

在现代,由于是 32 位,尤其是对于 Delphi 生成的非常胖的可执行文件,这些大小问题并不重要。因此,所有合理的建议都是只使用虚拟方法。

虚拟方法表的实现很好理解,可以找到很多参考资料来理解它们。对于相当古怪的动态方法来说,情况就不是这样了。我发现的最佳信息来源来自 Hallvard Vassbotn 的博客:

【讨论】:

  • +1 与最新的 Delphi 版本生成的巨大可执行文件大小相比,动态增益确实是徒劳的。
  • +1 很好的解释!!太感谢了!!我会阅读整篇论文
  • 如果 DMT 将被排序(由编译器),Delphi 中的 DMT 实现(主要用于调度窗口消息)可能会快得多,因此可以使用二进制搜索而不是线性搜索搜索找到方法指针。
  • AFAIR,还有一个最后调用的动态方法地址的缓存,所以如果被重复调用,在所有祖先的DMT中搜索它并没有太多的开销。而且,“消息”方法实际上是动态的。总是。
  • 所以,总结一下,当你派生一个孩子时,VMT表被完全复制,而DMT没有被复制,而只是“扩展”(添加到孩子的新方法只被持有孩子的 DMT)。对吗?
猜你喜欢
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2013-05-17
  • 2012-11-02
  • 2013-07-21
  • 1970-01-01
  • 2010-11-06
  • 1970-01-01
相关资源
最近更新 更多