C++中私有继承后成员偏移量是否与原类一致?
ISO C++标准是否保证继承类与基类成员偏移量相等?
先看定义的类A:
struct A { consteval static size_t offsetX() { return offsetof(A, x); } consteval static size_t offsetY() { return offsetof(A, y); } consteval static size_t offsetZ() { return offsetof(A, z); } friend class B; private: float x, y; int z; };
再看类B的定义:
struct B : private A { using A::x; using A::y; using A::z; };
问题:ISO C++标准是否能保证以下等式成立?
offsetof(B, x) == A::offsetX() offsetof(B, y) == A::offsetY() offsetof(B, z) == A::offsetZ()
能保证这些等式绝对成立,原因如下:
- 首先,
B是A的私有继承类,普通非虚继承不会改变基类子对象的内存布局:B对象内部的A子对象,其成员的相对偏移和独立的A对象完全一致,而且基类子对象的起始地址就是B对象的起始地址(没有额外偏移)。 using A::x这类声明只是把基类的私有成员引入到B的作用域中,让代码可以直接通过B访问这些成员,但完全不会改变成员在内存中的实际位置。offsetof(B, x)计算的是B对象中x成员相对于B起始地址的偏移,而这个偏移本质就是A子对象里x的偏移,和offsetof(A, x)完全相等。- 另外,
A和B都是标准布局类型(没有虚函数、成员访问控制没有交叉混排等不符合标准布局的情况),符合offsetof的标准使用要求,C++标准明确规定这类类型的offsetof结果是可靠的,且派生类中基类成员的偏移与基类中一致。
内容的提问来源于stack exchange,提问作者The Floating Brain
相关产品推荐
相关产品推荐

