派生类内基类的大小

时间:2017-01-16 09:31:23

标签: c++

假设我的课程没有数据:

struct Empty {
  /*some methods here*/
};

派生类

struct Derived: Empty {
  int a;
  int b;
  char c;
  ....
}__attribute__((packed));`

Empty类的对象具有size = 1.派生类的空部分通常具有0大小。据我所知,编译器看到基类Empty类没有数据,因此它可以优化Empty的大小,以防它是"内部"派生但不需要按标准执行。

所以问题是:

我可以在编译时以某种方式确定Derived类的Empty部分并不真正占用内存。

我知道我可以像sizeof(Derived) = sizeof(a) + sizeof(b) ...一样检查但是它太冗长了,并且有像Derived这样的几个类。有更优雅的解决方案吗?

2 个答案:

答案 0 :(得分:12)

您可以使用std::is_empty确保您继承的班级为零:

static_assert(std::is_empty<Empty>{});

如果是,empty base optimizationguaranteed to take place for standard-layout classes

  

我知道我可以像sizeof(Derived) = sizeof(a) + sizeof(b) ...一样检查但是它太冗长了。有更优雅的解决方案吗?

这不能正常运行,因为您需要考虑填充和最终属性,例如packed

答案 1 :(得分:3)

你可以使用更多&#34; old&#34; (之前 C ++ 11)宏 - offsetof

struct Empty {};
struct NonEmpty {
  int a;
};
struct Derived1: Empty {
  int a;
  int b;
  char c;
};
struct Derived2: NonEmpty {
  int a;
  int b;
  char c;
};
static_assert(offsetof(Derived1,a) == 0,"");
static_assert(offsetof(Derived2,a) != 0,"");

您也可以使用此宏来检查成员变量的顺序:

static_assert(offsetof(Derived,a) < offsetof(Derived,b),"");
static_assert(offsetof(Derived,b) < offsetof(Derived,c),"");

但不要忘记 - offsetof具有相同的限制:

  

如果type不是标准布局类型,则行为未定义。   如果member是静态成员或成员函数,则行为未定义。