Class Layout
461.37 KB
51 页
0 评论
语言 | 格式 | 评分 |
---|---|---|
英语 | .pdf | 3 |
摘要 | ||
文档详细阐述了C++中类的布局特性,重点介绍了标准布局类型(standard-layout types)和POD类型的定义与区别。标准布局类型保证了类的第一个非静态数据成员位于偏移量为零,其他成员按声明顺序排列,并且内存连续。POD类型则更为严格,排除了私有或受保护的非静态数据成员、用户声明的构造函数和基类。此外,文档还探讨了如何通过编译器扩展和静态断言来验证类的布局,以及多基类继承和虚函数对类布局的影响。最后强调了遵循标准布局的重要性,以避免潜在的内存对齐和布局问题。 | ||
AI总结 | ||
以下是对文档内容的总结,按照逻辑结构和核心内容进行梳理,语言简洁明了:
---
# 类布局总结
## 1. 标准布局类型
- **定义**:标准布局类型在C++11中被正式定义,旨在提供可预测的对象布局。
- **POD类型**(Plain Old Data):
- POD类型是标准布局类的一种特殊情况。
- POD类型不能有私有或受保护的非静态数据成员、用户声明的构造函数或基类。
- POD类型显得过于受限,C++20已弃用`is_pod`型特。
- **标准布局类**:
- 必须是C类型(如标量、数组或标准布局类)。
- 可以有非虚函数、静态成员函数、静态数据成员和嵌套类型。
- UART类是一个典型的标准布局类示例。
---
## 2. 布局保证与内存排列
- **布局保证**:
- 标准布局类的第一个非静态数据成员偏移量为零。
- 后续非静态数据成员的偏移量递增。
- 对象的存储是连续的。
- **填充字节**:
- 编译器可能在数据成员之间插入填充字节(即“空缺字节”)。
- 这使得除了第一个数据成员外,其他数据成员的偏移量不一定可预测。
- **示例**:UART类中ULCON数据成员的偏移量为零,但其他数据成员的偏移量无法确定。
---
## 3. 基类布局
- **基类子对象的排列**:
- 基类子对象的存储顺序是未指定的,但通常按照基类声明的顺序排列。
- 派生类的数据成员通常在基类子对象之后排列。
- **多继承下的派生类布局**:
- 在多继承情况下,派生类可能包含多个vptr(虚表指针)。
- 每个基类子对象可能有不同的虚表。
---
## 4. 内存填充与控制
- **填充字节的影响**:
- 编译器可能添加填充字节以满足对齐要求。
- 填充字节会影响数据成员的偏移量。
- **控制布局**:
- 部分编译器支持非标准扩展,如`#pragma pack`或`__attribute__(packed)`,可以压缩结构体布局。
- 静态断言(`static_assert`)可以用于验证数据成员的偏移量,避免运行时错误。
---
## 5. 注意事项
- **避免布局假设**:
- 不要假设类成员的物理排列与代码中的声明顺序一致。
- 使用`defaulted`特性(如`operator <=>`)时,数据成员的逻辑顺序与物理排列可能不一致。
- **虚函数与多继承**:
- 虚函数和虚基类会增加对象的复杂性,影响布局。
- 多重继承可能导致基类子对象重复,应尽量避免。
---
## 6. 示例与实际应用
- **UART类**:
- 假设UART类是标准布局类,用于设备建模,其成员偏移量需通过`static_assert`验证。
- **空类与状态**:
- 空类(无数据成员、虚函数或虚基类)仍需占用内存,通常为1字节。
通过以上总结,可以更清晰地理解C++类布局的核心概念、布局保证和实际应用中的注意事项。 |
P1
P2
P3
P4
P5
P6
P7
P8
P9
P10
P11
P12
下载文档到本地,方便使用
- 可预览页数已用完,剩余
39 页请下载阅读 -
文档评分