虚继承是否会增加额外的开销?

4
假设我有这个类:
class A{
};

还有这个派生类:

class B : public virtual A{
};

接着,B 没有任何派生类。

声明 B 为虚函数会增加不必要的开销吗?


3
为什么不制作一个带有 virtual 修饰符和一个没有 virtual 修饰符的程序版本,并查看生成的代码是否有任何不同。 - Barmar
你可能是指"声明A为虚拟的"。 - Sam Varshavchik
@Barmar 可能是因为编译器在这种比较方面通常是难以预测的。 - user253751
据我所记,有时它比动态转换还要糟糕。 - lorro
2个回答

3
我认为虚拟继承可能需要额外的开销,尽管这可能取决于编译器如何实现非虚拟继承。
普通继承可以通过简单地将派生类的成员连接到基类(类似于将基类作为派生类的第一个成员)来实现。访问基类的成员是从对象开始的简单偏移量,就像访问派生类的成员一样。
但是对于虚拟继承,必须通过指针进行间接引用。这允许所有从相同基类虚拟继承的类具有指向基类共享数据的指针。因此,访问基类的成员需要首先索引虚拟指针,解除引用它,然后索引成员的偏移量。
即使没有进一步的派生,这个开销也必须在派生类中存在,因为编译器无法确定您是否可能在与该类链接的其他编译单元中进行进一步的派生。它可以使用一些链接器魔法来链接不同版本的代码,具体取决于是否存在进一步的派生。但是,这意味着在B的形式中会有两个代码版本,这本身就产生了一些开销。
有关详细信息,请参见多重和虚拟继承的内存布局

提供的链接非常有助于理解虚拟继承。 - DarthRubik

0

是的。访问虚基类成员时涉及到间接性。


1
编译器如何知道是否有第二个派生类?第二个派生类可能在另一个编译单元中。 - Barmar
@Barmar 虚拟化很难,无论是在运行时还是编译时。 - edmz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接