2013-09-27 32 views
0

我有以下的基类,我检查了这个类的大小,它显示了16个字节。 如果我删除虚拟关键字fun(),然后它显示4字节。为什么基类的大小显示16个字节?

我不理解这种行为。任何指针?

class base 
{ 
     public : 
     int a; 
     virtual void fun() 
     { 
     } 
}; 

gcc版本:gcc版本4.1.2 20080704

操作系统:Linux 2.6.18-308.el5#1 SMP周五01月27日17时17分51秒EST 2012 x86_64的x86_64的x86_64的GNU/Linux的

回答

0

井“的指针”,实际上是猜对了。除了显式声明的数据字段之外,每个多态类还存储一些额外的“隐藏”信息。在一个典型的实现中,它将存储一个指向所谓的虚拟方法表(VMT)的指针。该指针的大小恰恰是在你的情况下为该类的大小增加了额外的字节。

显然,你是一个64,但平台,它采用了8字节的指针上编译代码。因此,对于VMT指针,您的类的总大小为8,int a字段为4,另外4个填充字节将类大小与8字节边界对齐。如果在32位模式下编译代码,则此类的sizeof可能评估为8.

在单继承层次结构中,所有类通常都会“共享”层次结构中最顶层多态类引入的指针,这意味着任何多态类的大小都会随着单个指针的大小而增长。但是在多继承层次结构中,最终可能会在一个类中包含多个隐藏的VMT指针,这意味着此类的大小将随着多指针的大小而增大。

7

你的编译器显然是存储每个实例来支持虚拟调度机器内部的指针(这是很常见的,它被称为v-表指针)。由于您使用的是64位架构,因此都会将8个字节添加到类的大小,并且还会使对齐8个字节。大小总是必须是对准的倍数以使阵列元件的对准工作,所以会有用于对准原因4个字节的填充,合计16。

1

若要实现虚拟方法多态行为或虚拟基类在运行时,编译器实现添加某些隐藏的成员。这是编译器和平台特定的行为。任何多态类的大小可能因编译器的不同实现而异。

这使得C++对象存储器模型以C内存模型不兼容的。

相关问题