首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有虚拟基和虚拟函数的派生类的大小

具有虚拟基和虚拟函数的派生类的大小
EN

Stack Overflow用户
提问于 2013-08-22 19:36:18
回答 1查看 1.1K关注 0票数 1

我在C++虚拟继承方面遇到了问题。

我有如下的类层次结构:

代码语言:javascript
复制
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与衍生价值--8字节
  2. 指针表示基类(虚拟继承的特性)的成员偏移量--4字节
  3. 指针表示基类的虚函数表-4字节
  4. Func2()指针表示仅属于派生类-4字节的虚函数(据我所知,没有非虚拟基类并获得其唯一虚拟函数的派生类应该有自己的虚拟表)。

之和可达20个字节;

然而,Xcode 4.6产生了sizeof(Derived)==16的不同结果,我是否弄错了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-22 19:51:18

指针表示基类的虚函数表-4字节 指针表示仅属于派生类-4字节的虚拟函数Func2() (据我所知,派生类没有非虚拟基类并获得其唯一的虚拟函数,因此应该有自己的虚拟表)。

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

然后,如果创建了Base的一个实例,您在Base表中提到的函数表指针,对Func的任何调用都将被重定向到Base::Func

如果创建了Derived的实例,则它的内部Base对象的虚拟函数表指针将指向Derived表。Base只知道如何访问Func指针,但是Func指针现在指向Derived::Func,所以这就是get的名称。它没有意识到它指的是另一张桌子。在代码中,它可能看起来更像这样:

代码语言:javascript
复制
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的虚拟函数表,实际上,这正是虚拟函数的神奇之处。

(随处可见的假设,这些都是定义不清的,虚拟继承使事情复杂化等等)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18389356

复制
相关文章

相似问题

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