如何用虚函数确定sizeof类?

时间:2011-01-22 05:23:06

标签: c++ sizeof vtable

这是一个功课问题。对于以下代码,

#include <iostream>
using namespace std;

class A
{
public:
    virtual void f(){}
};

class B
{
public:
    virtual void f2(){}
};

class C: public A, public B
{
public: 
    virtual void f3(){}
};

class D: public C
{
public:
    virtual void f4(){}
};

int main()
{
    cout<<sizeof(D)<<endl;
}

输出为:8

有人可以解释一下它是8字节吗?如果vtable实现依赖于编译器,那么在采访中我应该回答这类问题?那么虚拟基类呢?

编辑:我正在使用32位平台。

4 个答案:

答案 0 :(得分:13)

这当然是依赖于实现的。它会成为一个糟糕的面试问题。一个优秀的C ++程序员可以信任sizeof是正确的,让编译器担心那些可用的东西。

但是这里发生的事情是,典型的基于vtable的实现需要在类CD的对象中使用两个vtable。每个基类都需要自己的vtable。 CD添加的新虚拟方法可以通过从一个基类扩展vtable格式来处理,但AB使用的vtable不能组合

在伪C代码中,这是D类型的派生对象在我的实现中的表现(g ++ 4.4.5 Linux x86):

void* D_vtable_part1[] = { (void*) 0, &D_typeinfo, &A::f1, &C::f3, &D::f4 };
void* D_vtable_part2[] = { (void*) -4, &D_typeinfo, &B::f2 };

struct D {
  void** vtable_A;
  void** vtable_B;
};

D d = { D_vtable_part1 + 1, D_vtable_part2 + 1 };

答案 1 :(得分:2)

在这个问题中,如果你试图获得Sizeof A类,它会给你答案'4',因为A只有一个虚函数,所以它的__vptr将是'4'字节。

同样地,如果你试图获得Sizeof B类,它会给你答案'4',因为B也只有一个虚函数,所以它的__vptr将是'4'字节。

但是C类继承了A和A类。 B和C本身具有虚函数。因此C将接收2个__vptr指针,并且对于它自己的虚函数C将使用继承的__vptr。 因此,如果您尝试获取Sizeof C类,它将给出答案'8',因为C有两个虚拟指针。

最后D类继承C类,因此D将使用继承的__vptr作为自己的虚函数,因为C类的大小为'8'字节,所以sizeof D会给你答案'8'字节。

答案 2 :(得分:0)

原谅我含糊不清,但你提到它本质上是家庭作业。

查看sizeof()返回的其他类的内容。您的答案将根据您的编译器以及您是在32位还是64位环境而有所不同。

快乐的天意!

答案 3 :(得分:-1)

对象的大小与它拥有的方法数量无关,也与这些方法是否为虚拟无关。对象的大小由其成员变量 确定。

我无法确切地告诉您为什么要获得8字节的大小。由于您的类中没有数据成员,因此C ++编译器原则上可以生成一个根本不占空间的类[1]!我猜测8字节是提供指向vtbl的指针所需的最小值,加上可能还有一些填充。

[1]我想。现在没时间查看规范以了解sizeof是否可以返回0。