虚拟继承是否会增加派生类的大小?

时间:2012-06-15 00:17:42

标签: c++ size virtual-inheritance

  

可能重复:
  object size with virtual

虚拟继承是否会改变派生类的大小?我执行了以下代码,其中有两个派生类,一个是虚拟继承的,另一个是非虚​​拟继承的:

class A {
 public:
int a;
  virtual void a1();
};


class non_vir_der: public A{
 public:
int c;
  virtual void aa();
};


class vir_der: public virtual A{
public:
int d;
virtual void bb();
};

int main()
{
cout<<sizeof(non_vir_der)<<"\n";
cout<<sizeof(vir_der)<<"\n";
return 0;
}

输出:

12(imo:4(int a)+ 4(int c)+ 4(vir ptr))

16(额外4?)

再次检查我是否遗漏了某些东西,我尝试了所需的最小代码,删除了类中的所有整数,输出为:

4

4

第二个输出表明两个派生类的大小相同。 为什么第一次运行时vir_der 16的大小,为什么不是12?

2 个答案:

答案 0 :(得分:6)

此行为完全针对特定于实现,并且无法保证将会发生什么。也就是说,大多数编译器通过使用基类的单个副本来实现虚拟继承,然后让派生类的每个实例在其类主体内存储指向该唯一实例的指针。这样,如果将对象转换为其虚拟基础,编译器可以发出代码以找出该对象的位置。在32位系统上,这意味着虚拟继承可能会将对象的大小增加四个字节,正如您所观察到的那样。

那么,如果没有数据成员,为什么没有区别?我不确定,但我猜这是因为编译器足够聪明地意识到如果你有一个没有数据成员的虚拟基类,你实际上并不需要访问其中包含的任何内容。因此,可以通过消除指向虚拟基础的额外指针来优化对象,因为从来没有一种方法可以访问它。不过,我可能错了。

希望这有帮助!

答案 1 :(得分:0)

基本上,当您声明一个函数或类virtual时,编译器会实例化一个虚拟

在UPCAST​​ING的情况下需要的

指针。实际上,创建了一个虚拟指针表

其中所有虚拟实例都以其实际地址存储。因此,当您继承

第二种情况下的虚拟类,创建了额外的* vptr。

现在是第二种情况,为什么在这两种情况下都是4 ......这完全是编译器特定的。

根据简单的逻辑,第一种情况应为1,第二种情况应为4种。

感谢名单