假设我有这门课程:
class A{
};
这个派生类:
class B : public virtual A{
};
然后没有任何东西来自B
。
声明B
虚拟添加开销不需要在那里吗?
答案 0 :(得分:3)
我认为虚拟继承可能需要少量的额外开销,尽管它可能取决于编译器如何实现非虚拟继承。
可以通过简单地将派生类的成员连接到基类来实现正常继承(类似于将基类作为派生类的第一个成员)。访问基类的成员是从对象开头的简单偏移,就像访问派生类的成员一样。
但是对于虚拟继承,必须通过指针进行间接寻址。这允许所有从同一个基本上继承的类具有指向基类的共享数据的指针。因此,访问基类的成员需要首先索引到虚拟指针,解除引用,然后索引到成员的偏移量。
即使没有进一步的派生,这个开销也必须在派生类中,因为编译器无法判断您是否可以在与此类链接的其他编译单元中进一步派生。可以想象它可以使用一些链接器魔术来链接不同版本的代码,具体取决于是否有进一步的推导。但这意味着它有两个版本的B
代码形式的开销。
有关其他详细信息,请参阅 Memory Layout for Multiple and Virtual Inheritance
答案 1 :(得分:0)
是。访问虚拟基类的成员时会涉及间接。