C++ 为什么基类的大小显示为16字节?

C++ 为什么基类的大小显示为16字节?,c++,linux,virtual,C++,Linux,Virtual,我有以下基类,我检查了这个类的大小,它显示16字节。 如果我从fun()中删除virtual关键字,则显示4字节。 我不理解这种行为。有什么建议吗 class base { public : int a; virtual void fun() { } }; gcc版本:gcc版本4.1.2 20080704 OS:Linux2.6.18-308.el5#1 SMP Fri Jan 27 17:17:51 EST 2

我有以下基类,我检查了这个类的大小,它显示16字节。 如果我从fun()中删除virtual关键字,则显示4字节。

我不理解这种行为。有什么建议吗

class base
{
        public :
        int a;
        virtual void fun()
        {
        }
};
gcc版本:gcc版本4.1.2 20080704


OS:Linux2.6.18-308.el5#1 SMP Fri Jan 27 17:17:51 EST 2012 x86_64 x86_64 x86_64 GNU/Linux

您的编译器显然在每个实例中存储了一个指针以支持虚拟调度机制(这非常常见,称为v表指针)。由于您使用的是64位体系结构,因此这既增加了类大小的8个字节,也使对齐增加了8个字节。为了使数组元素的对齐工作,大小始终必须是对齐的倍数,因此出于对齐原因,将有4个字节的填充,总共16个。

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

<>这使得C++对象内存模型与C内存模型不兼容。

“任何指针”实际上是正确的猜测。除了显式声明的数据字段外,每个多态类还存储一些额外的“隐藏”信息。在典型的实现中,它将存储一个指向所谓的虚拟方法表(VMT)的指针。指针的大小正是在您的情况下为类的大小贡献额外字节的大小

显然,您是在使用8字节指针的64-but平台上编译代码的。因此,对于VMT指针,类的总大小为8,对于
inta
字段,类的总大小为4,另外4个填充字节用于将类大小与8字节边界对齐。如果在32位模式下编译代码,该类的
sizeof
值可能为8

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