使用vtable是在C ++中实现虚拟成员函数机制的唯一方法吗?还有其他什么方式?
答案 0 :(得分:11)
从技术上讲,动态调度所需的全部功能是能够在给定指针的情况下识别对象的动态类型。因此,任何类型的隐藏(或不那么隐藏) typeid 字段都可以。
动态调度将使用该typeid查找关联的函数。该关联可以是hastable或数组,其中typeid是索引,或任何其他合适的关系。 vptr恰好是以最少的步骤实现这一目标的方法。
答案 1 :(得分:3)
另一种可能的实现方式是将指向虚函数的指针直接存储到对象中。当然,这种解决方案从未在实践中使用过(至少在我所知的语言中),因为它会导致内存占用量的急剧增加。但是,值得注意的是,使用此实现的代码实际上可以更快地运行,因为它通过抑制对vptr的需要来删除间接层。
答案 2 :(得分:3)
另一种已知的机制是类型调度功能。实际上,您可以用typeid(小枚举)替换vtable指针。 (dyanmic)链接器收集给定虚函数的所有覆盖,并将它们包装在typeid字段的一个大switch语句中。
理论上的证明是,这取代了许多可预测跳跃的间接跳跃(不可预测)。有一些智能选择枚举值,switch语句也可以相当有效(即优于lineair)
答案 3 :(得分:2)
我不知道任何编译器在不使用vtable方法的情况下实现虚函数。
然而,从理论上讲,可以创建一个对象指针的内部映射和一个指向虚函数的指针,如map<objPtr, functionTable*>
,以实现动态通过虚函数进行多态性。但是它会使动态调度比vtable-approach慢。
似乎vtable-approach可能是实现动态多态的最快机制。也许,这就是为什么所有编译器都采用这种方法的原因!