在我的理解中,对于C++虚拟调用,它需要:
而对于非虚拟(例如在C)呼叫,仅需要#4.
我认为#3应该是最耗时的.鉴于C++中实时覆盖的性质,我看不到上述步骤的编译时间优化的可能性.因此,对于具有长函数签名的复杂类继承,C++虚拟调用应该比非虚拟调用慢得多.
但所有的说法都是相反的,为什么?
- 从符号表中获取对象的类型
- 从类型表中获取v表
- 使用v表中的函数签名搜索函数
- 调用该函数.
这对基于v-table的调度如何工作的理解很差.它更简单:
每个对象都有一个v表指针,该指针指向该对象原始类型的v表.所以不需要从"符号表"中获取类型.不需要搜索v表.根据编译时提供的函数签名,编译时可以确切地确定需要访问v表中的哪个指针.这完全是关于编译器如何索引类中的每个虚函数.它可以确定每个虚函数的特定顺序,因此当编译器调用它时,它可以确定要调用的函数.
所以它整体来说非常快.
处理虚拟基类时,它有点复杂,但总体思路仍然相同.
与普通函数调用相比,虚拟函数调用的开销是两个额外fetch操作(一个用于获取 v 指针的值,第二个用于获取方法的地址)。
在大多数情况下,这种开销不足以在性能分析中显示出来。
此外,在某些情况下,如果virtual可以在编译时确定要调用的函数,智能编译器将这样做,而不是在运行时确定。