MST

星途 面试题库

面试题:C++中class与struct内存布局差异之复杂场景与优化

考虑一个复杂场景,有多层继承和不同访问修饰符的情况:class Base1 { private: int a; protected: char b; public: float c; }; struct Intermediate : Base1 { int d; }; class Final : Intermediate { private: double e; public: bool f; }; 在64位系统下,且使用自定义对齐方式(#pragma pack(4)),请详细描述Final类实例的内存布局,并阐述如何通过调整成员顺序优化内存占用。同时分析如果是struct Final : Intermediate { private: double e; public: bool f; }; 这种情况与class Final的内存布局和优化情况的异同。
37.8万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

Final类实例的内存布局

在64位系统下,使用#pragma pack(4)自定义对齐方式,分析Final类的内存布局:

  1. Base1部分
    • private: int aint通常为4字节,按4字节对齐。
    • protected: char bchar为1字节,按4字节对齐,需填充3字节达到4字节对齐。
    • public: float cfloat为4字节,按4字节对齐。
    • Base1类大小为4 + 4 + 4 = 12字节(由于#pragma pack(4),每个成员按4字节对齐,char后填充3字节)。
  2. Intermediate部分
    • int dint为4字节,按4字节对齐。
    • Intermediate类继承自Base1,其大小为12 + 4 = 16字节。
  3. Final部分
    • private: double edouble为8字节,按4字节对齐,需填充4字节达到8字节对齐。
    • public: bool fbool为1字节,按4字节对齐,需填充3字节达到4字节对齐。
    • Final类继承自Intermediate,其大小为16 + 8 + 4 = 28字节(总大小为28字节,因为对齐方式为4字节,double后填充4字节,bool后填充3字节)。

内存占用优化

  1. 调整成员顺序:将成员按照占用字节数从大到小排列,可减少填充字节。例如,将Final类成员顺序调整为double efloat cint aint dchar bbool f
    • double e:8字节,按4字节对齐,无需填充。
    • float c:4字节,按4字节对齐,无需填充。
    • int a:4字节,按4字节对齐,无需填充。
    • int d:4字节,按4字节对齐,无需填充。
    • char b:1字节,按4字节对齐,需填充3字节。
    • bool f:1字节,按4字节对齐,需填充3字节。
    • 调整后Final类大小为8 + 4 + 4 + 4 + 4 + 4 = 28字节(原布局也是28字节,但在更复杂情况下,此调整可能优化内存)。

struct Finalclass Final的异同

  1. 内存布局
    • 相同点:在这种继承结构下,内存布局是相同的。因为structclass在继承和成员布局上遵循相同的规则,只是默认访问修饰符不同(struct默认publicclass默认private),而这里显式指定了访问修饰符,所以内存布局不受影响。
    • 不同点:理论上,如果没有显式指定访问修饰符,struct Final中继承自Intermediate的成员默认是publicclass Final中继承自Intermediate的成员默认是private。但在本题中显式指定了访问修饰符,所以在内存布局上没有不同。
  2. 优化情况
    • 相同点:优化方式和效果是相同的。因为内存布局相同,调整成员顺序的优化策略对两者同样适用。
    • 不同点:无本质不同,因为优化主要基于内存对齐和成员顺序,与structclass的默认访问修饰符无关,本题又显式指定了访问修饰符。