c++ - 虚拟函数需要多少字节的额外内存?

标签 c++ memory virtual-functions

虚函数的结构有从简单到复杂的各种情况。什么因素决定了所需的额外内存数量?例如

class A            {virtual void F() {}   };
class B : public A {virtual void F() {}   };

与没有虚函数的类相比,A 和 B 需要多多少内存?另一个带有 2 个虚拟函数的示例,

class A            {virtual void F() {}   virtual void G() {}   };
class B : public A {virtual void F() {}   virtual void G() {}   };

和示例 3

class A            {virtual void F() {};   virtual void G() {}  };
class B : public A {virtual void F() {}                         }; 

[--------------- 添加更多有趣的问题 ------------------]

  1. 每个虚方法都有一个虚方法表吗?如果是这样,我认为对于一个类(不是对象,对吧?我认为VPTR是静态的。)具有多个虚方法需要多个VPTR,每个VPTR对应一个虚方法。对吗?

  2. 是否可以为所有虚拟方法只构建一张表,并在一个类中只放置一个 VPTR?

  3. 而且我认为由于使用了直接VPTR,所以虚函数的调用速度应该比手动if更快。对吗?

[--------------- 测试 ----------------]

我使用 VS2010 和 intel c++ 编译器进行了测试并展示了我的结果。

struct A
{
    static int s_i;
    int i;
    virtual void F()    {i+=1;}
    virtual void G()    {i+=2;}
};

struct B
    : public A
{
    int j;
    virtual void F()    {i+=3;}
    virtual void G()    {i+=4;}

    virtual void H()    {i+=5;}
};

struct C
    : public B
{
    virtual void F()    {i+=6;}

    virtual void H()    {i+=7;}
};

TEST(MemoryForVirtualMethod)
{
    CHECK_EQUAL(sizeof(A), 8);
    CHECK_EQUAL(sizeof(B), 12);
    CHECK_EQUAL(sizeof(C), 12);
}

从结果来看,我的结论是

(1)对于每个具有虚函数的对象,添加一个(隐藏指针)VPTR。

(2)为每个类,为该类的所有虚方法建立一个虚方法表。

(3) 将VPTR放在object中是为了实现动态调度,因为引用的类可能不是动态类。

(4) 该实现调用效率高(比手动 if 更快),但牺牲了一些内存。

非常感谢!

最佳答案

因为虚拟函数通常实现为 virtual method table (vtable) ,我猜测每个O(虚函数数量),每个对象有1个额外的指针。不像你想要的那么精确,但应该给出一个粗略的想法。 正如 @AlokSave 提到的,还有许多其他微妙之处,这些微妙之处是编译器特定的,并且可能不够一致,无法估计。

Typically, the compiler creates a separate vtable for each class. When an object is created, a pointer to this vtable, called the virtual table pointer, vpointer or VPTR, is added as a hidden member of this object

来源:Wikipedia

您重写的函数数量(如您的示例中所示)是(我猜测)无关紧要的,除非可以在编译时安全地确定要调用的函数,在这种情况下它可能被视为静态调度函数(第二个示例中的G())。这也取决于编译器。

compilers usually avoid using vtables whenever the call can be resolved at compile time.

最后,虚拟函数的速度成本可能比内存更大。

关于c++ - 虚拟函数需要多少字节的额外内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14473778/

相关文章:

c++ - 使用压缩对进行不明确的基类转换

C++函数返回指针,为什么这样做?

c++ - 内存泄漏问题

c - 使用动态内存分配在二维数组中添加值

c++ - 在成员函数中调用虚函数

c++ - 在 C++ 中画一个圆,而是画一个菱形

c++ - SWIG C++ 到 Python:将 std::list 作为参数返回给 Python

c - 在派生类中分配虚方法时如何处理 "incompatible pointer type"?

c++ - GetModuleHandle和包含 header 之间的区别

c++ - 虚函数调用错误函数,在C++和Cocos2dX中完全不同的名字