【问题标题】:How does virtual method invocation work in C++?虚方法调用在 C++ 中如何工作?
【发布时间】:2011-04-17 18:33:31
【问题描述】:

虚拟方法调用如何在 C++ 中工作?

【问题讨论】:

  • 嗯?你的意思是调用虚方法?这和打电话给普通人一样。让您的问题更具体。
  • 在 C++ 中 调用就像调用普通方法一样完成 object.foo(); 让我猜猜。你问的是实施?
  • 虚拟方法的实现是未定义的,所以这个问题毫无意义。作为旁注,在没有经验的情况下知道答案对你没有任何帮助(除非你想构建一个编译器,然后你无论如何都不会问这个问题)。

标签: c++ oop inheritance virtual


【解决方案1】:

通过虚拟表。

阅读这篇文章,http://en.wikipedia.org/wiki/Virtual_table

我可以在这里解释一下,但维基百科做得比我做得更好。

【讨论】:

  • 阅读该页面后,我认为这对初学者来说太可怕了。它没有包含足够有用的信息,以至于它很危险。关于效率的部分是彻头彻尾的误导,它链接到的论文是 1996 年的(那已经有十多年的历史了,从 gcc 2.96 开始(甚至不被认为是一个工作的 C++ 编译器,更不用说现代 C++ 编译器了))。关于替代方案的部分非常适合虚拟调度的相关讨论,绝对不适用于 C++(这对初学者来说并不明显)。
  • 20 多年了
【解决方案2】:

C++ 标准没有规定应该如何实现虚函数机制。

也就是说,我认为当前所有的 C++ 编译器都使用虚拟表。
对于包含至少一个虚函数的类,执行此操作的常用方法是拥有一个指向所谓虚表的隐藏指针,其中特定类的虚函数地址按编译器特定的顺序输入。
然后,每个构造函数都会将此隐藏指针设置为它所属的类的虚拟表。

【讨论】:

  • 实际上,虚拟表是最简单的方法,但其他方法已尝试并报告效率更高(无论是执行时间还是二进制大小),例如参见:groups.csail.mit.edu/pag/paste2005/slides/… 不是很详细但最后有很酷的图表表明虚拟表是比较中效率最低的方法。
  • 同意 VT 是最简单的(它使用最广泛的原因之一)。但是那些图表(哇),线条太平了,那里有一些时髦的东西。 “小程序由脚本生成”这一行也有点突出。我希望看到以所有三种语言实现的真实世界程序。不同类型的程序也会有不同的特点。
  • @Matthieu:哇,我又学到了新东西!谢谢,我相应地调整了我的答案。希望现在没事吧?
  • @Martin:我当然也希望在工作中看到这一点。然而,考虑替代方案是件好事。我认为vtable 方法遇到的主要问题是多重继承,我希望在更常见的简单继承情况下看到这样的图表,其中vtable 方法看起来非常理想。
  • @Matthieu:是的,我认为我们可以同意这一切都很好。我们只是需要更多信息。
【解决方案3】:

每个具有至少一个虚拟方法的类都有它的虚拟表 - 指向作为该类方法的函数的指针表。

在 COM 中被广泛使用。

【讨论】:

  • 每个类都没有虚拟表。首先,只有多态类才有 vtable,其次所有 vtable 是特定于实现的。标准只是说“你应该工作”,并没有说明如何工作,而 vtables 就是如何工作。
【解决方案4】:

使用 VTable 和函数指针。虚函数的函数指针将列在 VTable
MFC 使用消息映射而不是虚函数,这减少了大小限制。如果我们使用多个虚函数 VTable 最终会变得很大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    • 2016-04-13
    • 2010-10-17
    • 2013-10-24
    • 2012-10-10
    相关资源
    最近更新 更多