C++派生类继承基类时不同位域定义的内存大小差异问题求解
两个案例内存占用差异的原因
这一差异是C++位域分配规则和基类子对象内存布局规则共同作用的结果,主流编译器(GCC/Clang/MSVC)的实现逻辑如下:
- 相同类型的相邻位域可以打包进同一个存储单元,直到剩余空间放不下下一个位域为止;基类的存储单元在基类定义完成后就会被封装,哪怕有剩余空闲位,派生类也不能复用这部分空间,必须新开存储单元。
- 位域的底层类型仅决定位域的取值范围和最大支持位数,存储单元的分配属于实现定义行为,编译器会在符合对齐规则的前提下尽可能压缩空间。
案例1分析
class A { private: uint32_t a1 : 8; }; class B : public A { private: uint32_t a2 : 2; uint32_t a3 : 22; };
- 基类
A仅含一个占8位的位域,编译器优化时会将A的大小定为1字节,无需按uint32_t的4字节完整分配空间。 - 派生类新增的两个位域总长度为2+22=24位(3字节),刚好可以和基类的1字节拼接为连续的4字节空间,无额外对齐开销,最终
sizeof(B)为4。
案例2分析
class A { private: uint32_t a1 : 8; uint32_t a2 : 2; }; class B : public A { private: uint32_t a3 : 22; };
- 基类
A有两个连续的uint32_t类型位域,总长度为10位,编译器会按照底层类型uint32_t的大小(4字节)为A分配完整的存储单元,剩余22位作为基类的填充位,不允许派生类复用。 - 派生类新增的22位位域需要新开一个4字节的
uint32_t存储单元存放,最终总大小为4+4=8字节。
内容的提问来源于stack exchange,提问作者Rico
相关产品推荐
相关产品推荐

