除了虚函数表,C++虚函数还可以如何实现?

14

可能可以构建一些奇怪的机制来实现(例如基于嵌入式类型ID和函数ID的全局跳转表),但从未听说过其他可行的实现方式。 - Erik
1
你的意思是内部实现吗?如果是,那么这确实是最快的方法。你需要一个用于快速分派的数组,并且要存储指针。所以你最终会得到类似于vtable的东西。 - Šimon Tóth
@sharptooth:重复的问题,参见https://dev59.com/D2855IYBdhLWcg3wbjrO。 - Alok Save
@Als:在提问之前我进行了搜索,但没有找到那个。 - sharptooth
@sharptooth:或许是因为有太多相似标签的问题,我之所以能找到它只是因为我一段时间以前曾经提出过那个问题。 :) - Alok Save
@Als:我想问题在于一个实际上是两个问题(就我所看到的),而标题非常通用。就在一个小时前,我想问“我是否需要将.dbproj Visual Studio项目中的.dat文件添加到源代码控制中?”然后“相关问题”显示了这个问题在顶部:https://dev59.com/5EjSa4cB1Zd3GeqPFGg- - sharptooth
4个回答

11

从技术上讲,动态分派所需的仅是能够在给定对象指针的情况下识别出该对象的动态类型的能力。因此,任何形式的隐藏(或非隐藏)typeid字段都可以起作用。

动态分派将使用该typeid来查找相关函数。该关联可以是哈希表或数组,其中typeid是索引,或者是任何其他适当的关系。vptr只是以最少的步骤实现这一点的方法。


3

另一种可能的实现方式是直接将虚函数的指针存储到对象中。当然,在实践中从未使用过这种解决方案(至少在我所知道的语言中),因为它会导致内存占用量的大幅增加。但是,值得注意的是,使用此实现的代码实际上可以运行得更快,因为它通过消除vptr的需求来删除间接层。


3

另一种已知的机制是类型分派函数。实际上,您将vtable指针替换为typeid(小枚举)。(动态)链接器收集给定虚拟函数的所有覆盖,并在typeid字段上包装它们成一个大的switch语句。

理论上的正当理由是,这将一个间接跳转(不可预测)替换为许多可预测的跳转。通过智能地选择枚举值,switch语句也可以相当有效(即比线性更好)。


2

我不知道是否有任何编译器在不使用vtable方法的情况下实现了虚函数。

理论上,可以创建一个内部映射对象指针指向虚函数的指针表,例如map<objPtr, functionTable*>, 通过虚函数实现动态多态性。但是这将使动态分派比vtable方法慢。

看起来,vtable方法可能是实现动态多态性最快的机制。也许这就是为什么所有编译器都采用这种方法的原因!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接