2

我对 C++ 和虚拟继承很好奇——尤其是在 bass 和子类之间解决 vtable 冲突的方式。我不会假装理解它们如何工作的细节,但到目前为止我所看到的是它们是由于该分辨率而使用虚函数引起的一个小延迟。那么我的问题是,如果基类是空白的 - 即它的虚函数定义为:

virtual void doStuff() = 0;

这是否意味着不需要分辨率,因为只有一组函数可供选择?

如果这是一个愚蠢的问题,请原谅我——正如我所说,我不明白 vtables 是如何工作的,所以我真的不知道更好。

编辑

因此,如果我有一个带有两个单独子类的抽象类:

    A
   / \
  /   \
 B     C

从子类调用函数时没有性能损失,而不是说,只是一个单继承自由类?

4

3 回答 3

5

在子类中调用非虚拟函数没有任何影响。如果您像示例中那样调用纯虚函数的覆盖版本,则虚拟惩罚可能仍然存在。一般来说,编译器很难优化虚拟表的使用,除非在非常特殊的情况下,它知道所讨论对象的确切按值类型(从上下文中)。

但是,请不要担心开销。它是如此之少,以至于在实践中您几乎可以肯定永远不会遇到它是导致性能瓶颈的代码部分的情况。在对您的设计有意义的地方使用虚函数,并且不用担心(微小的)性能损失。

于 2010-06-18T15:09:59.233 回答
2

我不知道您在说什么“一组功能”。您有两个派生类 -B并且C- 每个都有自己的一组虚函数。因此,您至少有两个集合,即使其中的所有函数A都是纯函数。

当编译器不知道它正在使用的对象的动态类型时,就会发生虚拟分派。例如,如果您有一个指针A *p,它可以指向一个类型B或类型的对象C。如果编译器不知道对象p指向的实际类型是什么,它将不得不使用虚拟调度来调用虚拟函数p

PS您的示例中没有“虚拟继承”。C++ 中的术语虚拟继承有其自身的含义。而且您在这里谈论的不是虚拟继承。

于 2010-06-18T14:39:31.617 回答
0

只有当方法是虚拟的时才会发生“双重调度”命中。如果派生方法不是虚拟的,则不会影响性能。

于 2010-06-18T14:11:27.683 回答