派生类中基类的大小

Size of base class inside derived class

本文关键字:基类 派生      更新时间:2023-10-16

假设我有没有数据的类:

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

和一个派生类

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

空类的对象的大小 = 1。派生类的空部分通常具有 0 大小。据我了解,编译器看到基空类没有数据,因此它可以优化空的大小,以防它"在"派生内部",但标准不需要这样做。

所以问题是:

我可以在编译时以某种方式确定派生类的空部分并没有真正占用内存。

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

您可以使用

std::is_empty来确保从中继承的类的大小为零:

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

如果是,则保证对标准布局类进行空基优化


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

这无法正常工作,因为您需要考虑填充和最终属性,例如 packed .

您可以使用更多"旧"(在 C++11 之前)宏 - 偏移量:

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),"");

但不要忘记 - 偏移量具有相同的限制:

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