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

Why the size of base class showing 16 byte?

本文关键字:显示 16字节 基类 为什么      更新时间:2023-10-16

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

我不明白这种行为。 有什么指示吗?

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

GCC 版本:GCC 版本 4.1.2 20080704

操作系统 : Linux

2.6.18-308.el5 #1 SMP 美国东部时间 2012 年 1 月 27 日星期五 17:17:51 x86_64 x86_64 x86_64 GNU/Linux

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

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

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

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

显然,您正在使用 8 字节指针的 64 但平台上编译代码。因此,对于 VMT 指针,类的总大小为 8,对于int a字段为 4,以及用于将类大小与 8 字节边界对齐的填充字节数为 4。如果在 32 位模式下编译代码,则此类的sizeof计算结果可能为 8。

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