C++虚函数除了vtable怎么实现? [复制]

Posted

技术标签:

【中文标题】C++虚函数除了vtable怎么实现? [复制]【英文标题】:How can C++ virtual functions be implemented except vtable? [duplicate] 【发布时间】:2011-07-22 00:42:16 【问题描述】:

可能重复:A question about virtual mechanism in C++

在 C++ 中使用 vtable 是实现虚成员函数机制的唯一方法吗?还有哪些其他方式?

【问题讨论】:

可能会构建一些可行的奇怪机制(基于嵌入式类型 id 和函数 id 或其他东西的全局跳转表) - 但从未听说过其他实际可行的实现。 你是说内部?如果是,那么,这是最快的方法。您将需要一个用于快速调度的数组,并且您将存储指针。所以你最终会得到像 vtable 这样的东西。 @sharptooth:与***.com/questions/4352032/…重复 @Als:我在询问之前搜索并没有找到那个。 @sharptooth:可能有太多带有相似标签的问题。我能找到它只是因为我是前一阵子问这个问题的人。 :) 【参考方案1】:

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

然而,理论上,可以创建一个对象指针指向虚函数的指针表的内部映射,类似于map<objPtr, functionTable*>,通过以下方式实现动态多态性虚函数。但这会使动态调度比 vtable-approach 慢。

似乎 vtable-approach 可能是实现动态多态性的最快机制。也许,这就是所有编译器都采用这种方法的原因!

【讨论】:

【参考方案2】:

从技术上讲,动态分派所需要的只是能够识别对象的动态类型,给定一个指向它的指针。因此,任何类型的隐藏(或不那么隐藏)typeid 字段都可以工作。

动态调度将使用该 typeid 来查找关联的函数。该关联可以是一个 hastable 或一个 typeid 为索引的数组,或任何其他合适的关系。 vptr 恰好是用最少的步骤实现这一目标的方法。

【讨论】:

【参考方案3】:

另一种可能的实现是将指向虚函数的指针直接存储到对象中。当然,这个解决方案从未在实践中使用过(至少在我所知道的任何语言中),因为它会导致内存占用量的急剧增加。然而,有趣的是,使用此实现的代码实际上可以运行得更快,因为它通过抑制对 vptr 的需求来移除间接层。

【讨论】:

【参考方案4】:

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

理论上的理由是,这用大量可预测的跳跃代替了间接跳跃(不可预测的)。在选择枚举值方面有一些技巧,switch 语句也可以相当有效(即比 lineair 更好)

【讨论】:

以上是关于C++虚函数除了vtable怎么实现? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

c++虚函数问题,大神请进

C++中是否每个类(有虚函数)都对应一个virtual function table?

C++的构造函数为何不能为虚函数

C++性能榨汁机之虚函数的开销

虚表(Vtables)

C++类的构造函数不能为虚函数的原因