假设我的课程没有数据:
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这样的几个类。有更优雅的解决方案吗?
答案 0 :(得分:12)
您可以使用std::is_empty
确保您继承的班级为零:
static_assert(std::is_empty<Empty>{});
如果是,empty base optimization为guaranteed 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是静态成员或成员函数,则行为未定义。