C ++ Derived多态类 - 它是否包含一个完整的Base实例,包括一个vptr?

时间:2011-09-23 13:30:32

标签: c++ class virtual sizeof vptr

说我们有

Class A
{
   public:
   int _i;
   virtual int getI();
};
class B : public A
{  
   public:
   int _j;
   virtual int getI();
};

因此,假设内存中类的大小是其成员的总和(即忽略填充或实际可能发生的任何事情),B实例的大小是多少?是sizeof(A)+ sizeof(int)+ sizeof(vptr)?或者B实例不在其个人A实例中持有A vptr,因此sizeof(b)将是sizeof(int)+ sizeof(int)+ sizeof(vptr)?

4 个答案:

答案 0 :(得分:3)

这是使代码工作所需的任何实现。所有你 可以说它至少是2 * sizeof(int),因为它的对象 类型B包含两个int(可能还有其他内容)。在一个典型的 实施,AB将共享一个vptr,总大小将 只是一个指针超过两个整数(模数填充为 对齐,但在大多数实现中,我不认为会有 任何)。但这只是一个典型的实施;你不能指望它。

答案 1 :(得分:1)

关于vtable的任何讨论都将特定于某个实现,因为即使是vtable的存在也没有由C ++标准指定 - 它是一个实现细节。

通常,一个对象只有一个指向vtable的指针,该vtable将在该类型的所有对象之间共享。派生类将在表中包含指针,用于基类的每个虚函数以及它没有继承的每个新虚函数,但同样这是一个静态表,它是的一部分。对象

要真正回答这个问题,最有可能的结果是sizeof(B)== sizeof(A :: _ i)+ sizeof(B :: _ j)+ sizeof(vptr)。

答案 2 :(得分:0)

除了James Kanze所说的,或许值得一提的是(在一个典型的实现中)B的虚拟表将在其开头包含A的虚拟表。

例如:

class A {
    virtual void x();
    virtual void y();
};

class B : A {
    virtual void y();
    virtual void z();
};

A的虚拟表:

  • A:X()
  • A:Y()

B的虚拟表:

  • A:X()
  • 为:y()
  • B:Z()

这就是为什么B的实例可以只用一个虚拟表指针就可以了。

BTW,多重继承可能会使事情变得复杂,并为每个对象引入多个虚拟表指针。

请记住,所有这些都是一个实现细节,您永远不应该编写依赖于它的代码。

答案 3 :(得分:0)

你为什么想知道?如果你打算在你的程序中使用它,我会尝试寻找一种比计算它更便携的方法,并添加一个返回大小的虚函数,或者使用运行时类型信息来获得正确的类型然后返回大小。

(如果您投票或添加评论,我将开始装饰答案)