【问题标题】:C++ Polymorphic memory costC++ 多态内存开销
【发布时间】:2013-03-22 11:05:27
【问题描述】:

我有这段代码:

    #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 位。

【问题讨论】:

  • 更相关的是,您正在为哪个 CPU 编译?

标签: c++ polymorphism virtual-functions


【解决方案1】:

除了charunsigned 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。

【讨论】:

  • 是的,它是带有 g++ 4.6.3 的 64 位 linux mint。我应该提到这一点。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我认为成本是:

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

    sum=16 字节。

    【讨论】:

      【解决方案4】:

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

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

      因此总和变为 16。

      【讨论】:

        猜你喜欢
        • 2011-05-05
        • 2010-12-31
        • 2010-12-10
        • 2015-02-12
        • 1970-01-01
        • 2011-11-16
        • 2011-02-12
        • 2020-12-13
        • 1970-01-01
        相关资源
        最近更新 更多