gpt4 book ai didi

c++ - 具有虚基和虚函数的派生类的大小

转载 作者:行者123 更新时间:2023-11-28 07:27:50 24 4
gpt4 key购买 nike

我在使用 C++ 虚拟继承时遇到问题。

我有一个类层次结构如下:

class Base
{
public:
virtual void Func(){};
int BaseValue;
};

class Derived : virtual public Base
{
public:
void Func(){};
virtual void Func2(){};
int DerivedValue;
};

虽然编译得很好,但我对内存结构有点困惑。

我希望得到sizeof(Derived)==20的结果,即:

  1. BaseValue 和 DerivedValue--8 字节
  2. Pointer表示Base class的成员偏移量 (虚继承的特性)--4字节
  3. 指针表示Base类的虚函数表--4字节
  4. 指针表示只属于Derived类的虚函数Func2()--4字节(就我而言,没有非虚拟基类并获得其唯一虚拟函数的派生类应该有自己的虚拟表)

总共20个字节;

然而 Xcode 4.6 产生了不同的结果 sizeof(Derived)==16,我理解错了吗?

最佳答案

Pointer denotes the virtual function table of Base class--4 bytes
Pointer denotes the virtual function Func2() which only belongs to class Derived--4 bytes (as far as I'm concerned, derived class which has no non-virtual base classes and gets its unique virtual functions should has its own virtual table)

啊,我现在明白问题所在了。这不是完全虚函数表的工作方式。当定义Base时,编译器注意到它需要一个虚拟表,并为Base生成一个虚拟表,带有一个指针(Func),它指向 Base::Func 实现。当 Derived 被定义时,编译器注意到它继承自 Base,并为 Base 生成一个具有两个 指针,Func 指向Derived::FuncFunc2 指向Derived::Func2

然后,如果创建了 Base 的实例,那么您提到的函数表指针指向 Base 表,并且对 Func 的任何调用code> 将被重定向到 Base::Func

如果 Derived 的实例被创建,它的内部 Base 对象的虚函数表指针将指向 Derived 表。 Base 只知道如何访问 Func 指针,但是 Func 指针现在指向 Derived::Func,这就是所谓的 get。它没有意识到它指向不同的表。在代码中,它可能看起来更像这样:

using voidFunctionType = void(*)();

struct BaseVTable {
voidFunctionType Func;
}BaseVTableGlobal;

struct Base {
Base() :vTable(&BaseVTableGlobal) {}
void Func() {vTable->Func();}

BaseVTable* vTable; //4 bytes
int BaseValue; //4 bytes
}; //total is 8 bytes

struct DerivedVTable : public BaseVTable {
voidFunctionType Func;
voidFunctionType Func2;
}DerivedVTableGlobal;

//inherits 8 bytes, +4 for virtual inheritance = 12
struct Derived : virtual public Base {
Derived() :Base() {vTable = &DerivedVTableGlobal;} //the shared vTable points at DerivedVTableGlobal
void Func() {vTable->Func();} //base knows about Func, so this is easy
void Func2() {((DerivedVTable*)vTable)->Func2();} //base doesn't know about Func2

int DerivedValue; //4 bytes
}; //16 bytes total

所以 XCode 是对的。 Derived 是“劫持”Base 的虚函数表,事实上,正是虚函数发挥其魔力的方式。

(到处都是假设,没有一个是明确定义的,虚拟继承使事情复杂化等等)

关于c++ - 具有虚基和虚函数的派生类的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18389356/

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