0

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

我不明白这种行为。任何指针?

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

gcc 版本:gcc 版本 4.1.2 20080704

操作系统:Linux 2.6.18-308.el5 #1 SMP Fri Jan 27 17:17:51 EST 2012 x86_64 x86_64 x86_64 GNU/Linux

4

3 回答 3

7

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

于 2013-09-27T05:20:30.510 回答
1

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

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

于 2013-09-27T05:23:54.947 回答
0

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

显然,您正在使用 8 字节指针的 64 位平台上编译代码。因此,VMT 指针的类的总大小为 8,int a字段为 4,另外还有 4 个填充字节以将类大小与 8 字节边界对齐。如果你在 32 位模式下编译你的代码,sizeof这个类的值可能会计算为 8。

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

于 2013-09-27T05:31:35.523 回答