gpt4 book ai didi

c++ - 为什么极端向下派生类(多重虚拟继承)的大小包括父类(super class)成员大小的两倍?

转载 作者:太空狗 更新时间:2023-10-29 20:18:20 25 4
gpt4 key购买 nike

#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 表示锑
  • 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:Sb 4 个,a、b、c 各 4 个,三个 vtable 指针各 4 个,每个 in Base1、Base2 和派生。但是您的编译器(我认为)帮了您一个忙,并将 Derived 的 vtable 指针安排在与 Base1 相同的位置,这对于单继承来说是正常的。

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

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

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

关于c++ - 为什么极端向下派生类(多重虚拟继承)的大小包括父类(super class)成员大小的两倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4335071/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com