首页 > 解决方案 > 内存中继承类型的排序

问题描述

我可以假设一个类成员的内存位置无论如何都按照它们出现在它的定义中的顺序吗?

struct Color {
    uint8 r, g, b;
};
struct Vec3 {
    float x, y, z;
};

struct Object : public Color, Vec3 {
    uint32 data;
}object;

换句话说,将object.r永远在之前object.x,它自己永远在之前object.data

或者更具体地说,以下代码是否总是成立?

assert( offsetof(Object, b)    ==  offsetof(Color, b) );
assert( offsetof(Object, z)    ==  sizeof(Color) + offsetof(Vec3, z) );
assert( offsetof(Object, data) ==  sizeof(Color) + sizeof(Vec3) );

标签: c++inheritancememoryc++14

解决方案


您的类Object不是标准布局,因为它的(直接和间接)非静态数据成员并非都在同一个类中声明。

因此,几乎唯一的保证是,在同一个类中声明且具有相同访问说明符的成员根据其声明顺序进行排序:

r < g < b
x < y < z

并且子对象的子对象的顺序是一致的,即ifdata < rdata < b如此等等。

(名称应该在这里代表地址。)

我认为 C++ 标准没有任何其他保证,但您的平台使用的 ABI 将更详细地指定这一点。

顺便说一句,由于该类不是标准布局,offsetof因此在 C++14 中具有未定义的行为(并且自 C++17 起仅受条件支持)。

即使满足了排序要求,也不需要满足断言,因为子对象之间可以有填充。


推荐阅读