我对C ++和虚拟继承感到好奇 - 特别是在低音和子类之间解决vtable冲突的方式。我不会假装了解它们如何工作的具体细节,但到目前为止我所发现的是由于该分辨率使用虚拟函数导致的延迟很小。那么我的问题是基类是否为空 - 即,其虚函数定义为:
virtual void doStuff() = 0;
这是否意味着不需要分辨率,因为只有一组函数可供选择?
请原谅我,如果这是一个愚蠢的问题 - 正如我所说,我不明白vtable是如何工作的,所以我真的不知道更好。
修改
因此,如果我有一个带有两个单独子类的抽象类:
A
/ \
/ \
B C
从子类调用函数时,没有性能损失,比如说只有一个继承自由类?
答案 0 :(得分:5)
在子类中调用非虚拟函数没有任何意义。如果您在示例中调用纯虚函数的重写版本,则虚拟惩罚可能仍然存在。一般来说,编译器很难优化虚拟表的使用,除非在非常特殊的情况下,它知道相关对象的确切的按值类型(来自上下文)。
但严重的是不要担心开销。这将是如此之少,以至于在实践中你几乎肯定不会遇到这样的情况,即代码的一部分导致性能瓶颈。使用虚拟功能,它们对您的设计有意义,并且不用担心(微小的)性能损失。
答案 1 :(得分:2)
我不知道你在说什么“一套功能”。您有两个派生类 - B
和C
- 每个类都有自己的虚函数集。因此,即使A
中的所有函数都是纯函数,您至少还有两个集。
当编译器不知道正在使用的对象的动态类型时,就会发生虚拟调度。例如,如果您有一个指针A *p
,它可以指向类型为B
或类型为C
的对象。如果编译器不知道对象p
指向的实际类型是什么,则必须使用虚拟分派才能通过p
调用虚函数。
P.S。您的示例中没有“虚拟继承”。 C ++中的术语虚拟继承有其自身的含义。而你不是在谈论虚拟继承。
答案 2 :(得分:0)
“双重调度”命中仅在方法为虚拟时发生。如果派生方法不是虚拟的,则不会影响性能。