5

我有这段代码:

    #include <stdio.h>

    class CoolClass {
    public:
      virtual void set(int x){x_ = x;};
      virtual int get(){return x_;};
    private:
      int x_;
    };

    class PlainOldClass {
    public:
      void set(int x) {x_ = x;};
      int get(){return x_;}
    private:
      int x_;
    };
    int main(void) {
      printf("CoolClass size: %ld\n", sizeof(CoolClass));
      printf("PlainOldClass size: %ld\n", sizeof(PlainOldClass));
      return 0;
    }

我有点困惑,因为它说 CoolClass 的大小是 16?如何?为什么?即使有指向 vtable 的指针,大小不应该是 8 吗?正如预期的那样,oldclass 的大小为 4。

编辑:我正在使用 g++ 4.6.3 运行 Linux Mint 64 位。

4

4 回答 4

5

你不能假设任何东西的大小除了charor unsigned char。如果您在 64 位平台上构建,int可能仍然是 4 个字节,但虚拟表指针的大小可能是8,并且额外的 4 个字节用于填充(以便指针与 8 个字节对齐)。

64 位

+----+----+----+----+
| vp | vp | x_ | p  |
+----+----+----+----+

vp - virtual table pointer
x_ - member
p  - padding byte

32 位

+----+----+
| vp | x_ |
+----+----+

vp - virtual table pointer
x_ - member
p  - padding byte

Padding not required because the pointer is already aligned

作为测试,你可以试试

class PlainOldClass {
private:
  int* x_;
};

它的大小是8。

于 2013-04-01T11:14:38.023 回答
4

我最好的猜测是您正在为具有 64 位指针的平台进行编译。然后虚拟指针需要 8 个字节,可能需要 4 个字节int(一些 64 位平台也会提供 8 个字节 - 但你说sizeof (PlainOldClass)是 4,所以这里不适用),另外 4 个为类提供指针所需的 64 位对齐 - 总共 16 个字节。

于 2013-04-01T11:16:18.563 回答
2

我认为成本是:

  • 具有 64 位指针的平台,因此虚拟指针为 8 个字节
  • int 4 个字节(但在某些平台上也可能是 8 个字节)
  • 4 为类提供指针所需的 64 位对齐

总和 = 16 个字节。

于 2013-04-01T11:18:36.763 回答
1

这是因为你的系统可能是 64 位系统,因此它变成了,

  • vptr 为 8 个字节。
  • 4 个字节用于 int
  • 和额外的 4 字节填充以使指针保持 64 位对齐。

因此总和变为 16。

于 2013-04-01T11:29:59.393 回答