加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 为什么极端向下的大小派生类(多个虚拟继承)包括超类成员的

发布时间:2020-12-16 09:31:07 所属栏目:百科 来源:网络整理
导读:#include iostreamclass 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 namespac
#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
> 4表示
b> 4
> 4表示c
> 8表示虚拟继承的开销.

在我的(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++?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读