c – 为什么极端向下的大小派生类(多个虚拟继承)包括超类成员的
#include <iostream> class SuperBase { public: int Sb; }; class Base1:virtual public SuperBase { public: int a; }; class Base2:virtual public SuperBase { public: int b; }; class Derived: public Base1,public Base2 { public: int c; }; int main() { using namespace std; cout<<sizeof(Derived); return 0; } output is showing 24 but it should show 20 because int sb 4 bytes int a 4 bytes int b 4 bytes int c 4 bytes vbptr 4 bytes total 20 bytes 因为我们正在使用虚拟继承概念所以int sb不应该计算两次不是吗? 解决方法
24可能是:
> 4为Sb 在我的(32位)编译器上,sizeof(Derived)是24而sizeof(Base1)是12,但是,这表明开销并不总是8. 我猜测8由Base1子对象开头的一个vtable(或类似)指针和Base2子对象中的另一个指针组成,当指向对象的指针被转换为Base2 *时,将使用该指针.多重继承的问题是Base1从对象开始的偏移量不能与Base2从对象开始的偏移量相同. 特别是,这意味着对于Base1和Base2之一,当Derived的基类子对象与BaseN是最派生类时的偏移量不同.但是当你转换为Base2 *时,结果值必须指向“看起来像”Base2的东西.因此,在虚拟继承实际上导致共享基类的情况下会有一些额外的开销. 另一种方法是将sizeof(SuperBase)4,sizeof(Base1)和sizoef(Base2)都设为12(两个整数和一个vtable指针),sizeof(Derived)等于28:4为Sb,4每个用于a,b,c和4,每个用于三个vtable指针,分别在Base1,Base2和Derived中各有一个.但是你的编译器(我认为)帮了你一个忙,并安排Derived的vtable指针和Base1在同一个地方,就像单继承一样. 在所有情况下,当我说“vtable指针”时,它可能与用于虚函数的完全相同,但它可能是某种类元数据.也许它只是用于到达基类的指针或偏移量. 我在这里画了一些可能有帮助的小图: Why can’t you use offsetof on non-POD structures in C++? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |