我对此处提供的解释有疑问 http://www.parashift.com/c++-faq/virtual-functions.html#faq-20.4
示例代码中函数mycode(Base *p)
,调用virt3
方法作为p->virt3()
。在这里,编译器如何准确地知道 virt3 位于 vtable
的第三个插槽中?它与什么相比如何?
最佳答案
当编译器看到 Base
的定义时,它根据一些通用的算法1 决定它的 vtable
的布局它的派生类就继承自Base
的方法而言(派生类可以添加其他virtual
方法,但它们被放入vtable
< em>after 从 Base
继承的东西)。
因此,当编译器看到 p->virt3()
时,它已经知道对于任何继承自 Base
的对象,指向正确的 virt3 的指针
例如在 vtable
的第三个槽中(因为在定义时它就是这样布置 Base
的 vtable
的),所以它可以正确生成虚拟调用的代码。
长话短说(从@David Rodríguez 的评论中获得灵感):它知道它停留的位置,因为他决定之前。
1. 该标准没有强制要求任何特定的算法(实际上,它没有说明 C++ ABI 应该如何实现),但是有几个广泛使用的 C++ ABI 规范,特别是 Windows 上的 COM ABI 和 Linux 上的 Itanium ABI (通常对于 gcc)。显然,给定相同的类定义,算法必须每次都给出相同的 vtable 布局,否则就不可能将不同的目标模块链接在一起。
关于C++ 虚表查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7361938/