首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么极端向下的派生类(多重虚拟继承)的大小包含超类成员大小的两倍?

为什么极端向下的派生类(多重虚拟继承)的大小包含超类成员大小的两倍?
EN

Stack Overflow用户
提问于 2010-12-02 20:41:13
回答 5查看 364关注 0票数 3
代码语言:javascript
运行
复制
#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不应该计算两次,不是吗?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-12-02 20:46:55

24可能是:

  • 4 for Sb
  • 4 for a
  • 4 for b
  • 4 for c
  • 8虚拟inheritance.

的开销

在我的(32位)编译器上,sizeof(Derived)是24,sizeof(Base1)是12,这表明开销并不总是8。

我猜8由一个vtable (或类似的)指针组成,位于Base1子对象的开头,另一个位于Base2子对象中,当指向该对象的指针转换为Base2*时,将使用该指针。多重继承的问题是,Base1距对象开头的偏移量不能与Base2距对象起点的偏移量相同。

特别是,这意味着对于Base1和Base2中的一个,当它是派生的基类子对象时,偏移量与BaseN是最派生的类时不同。但是当你强制转换为Base2*时,结果值必须指向“看起来”像Base2的值。因此,在虚拟继承实际上导致共享基类的情况下,会有一些额外的开销。

另一种方法是使sizeof(SuperBase) 4、sizeof(Base1)sizoef(Base2)都为12 (两个it和一个vtable指针),并且sizeof(Derived)等于28: 4对于Sb,4分别对于a、b、c和4对于三个vtable指针,在Base1、Base2和派生中各一个。但是你的编译器(我认为)帮了你一个忙,并且安排了派生的vtable指针与Base1的vtable指针在同一位置,这对于单继承来说是很正常的。

在所有情况下,当我说"vtable指针“时,它可能是也可能不是用于虚函数的完全相同的东西,但它是某种类元数据。也许它只是一个指针或偏移量,用于到达基类。

我在这里画了一些可能会有帮助的小图表:

Why can't you use offsetof on non-POD structures in C++?

票数 4
EN

Stack Overflow用户

发布于 2010-12-02 20:53:47

通常,通过虚拟继承从其他类继承的类需要额外的指针或偏移量,以指示它们继承的每个虚拟基址所在的位置。根据它们所属的完整对象的类型,不能假设虚拟基地处于相同的相对位置。

指针实际上不需要指向基类本身,编译器可能会插入类型信息结构的id,该结构可以用来计算出对象的完整布局,但通常需要一些东西,以便当代码通过指针或引用使用像Base1这样的类时,它将始终工作,而不管特定Base属于哪个完整对象。

这意味着Derived中的Base1Base2的大小可能类似于sizeof(int) + sizeof(void*),在典型的32位编译器上,除了SuperBase的大小和Derived的成员的总大小之外,还有8个字节。

票数 2
EN

Stack Overflow用户

发布于 2010-12-02 20:56:27

记住要查看所有的大小-这样可以更容易地看到可能发生的情况。

在本例中,在我测试的编译器上,拥有一个虚拟基类会给Base1和Base2各增加4字节的开销。

代码语言:javascript
运行
复制
SuperBase           4
Base1               12
Base2               12
Derived             24
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4335071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档