c++ - 对象数据成员的 C++ 连续内存访问
问题描述
我很好奇 C++ 类的内存模型是如何工作的。具体来说,我是否保证对象的数据成员是连续分配的。例如,如果我有以下代码:
class Particle {
public:
Particle(double ix, double iy, double ivx, double ivy);
// Omitted for brevity
private:
double x;
double y;
double vx;
double vy;
};
当我初始化一个对象时,数据成员会在内存中是连续的还是我最好(为了性能)做这样的事情:
class Particle {
public:
Particle(double ix, double iy, double ivx, double ivy);
// Omitted for brevity
private:
std::array<double, 4> params
};
我来自 Fortran 和 C 编程背景,并且习惯于使用数组进行快速顺序内存访问,所以我很好奇当所有数据成员在任何调用中连续使用时,是否首选上述语义之一来进行快速访问。
解决方案
该标准保证它们将在内存中按该顺序排列
(如果您获取它们的地址,它们会增加)。它不保证它们会在连续的内存中;但如果这是最优化的布局,那么它们可能会是。允许编译器在成员之间添加填充(它通常这样做是为了提高访问效率(为了速度而牺牲空间))。如果所有成员的大小相同,则这是不可能的。
注意:在它们之间引入 public/private/protected 会使事情复杂化并且可能会改变顺序。
你最好使用数组吗?
那要看。您通常会通过索引还是通过名称访问它们?我会说 99% 的时间你拥有的第一个版本会更好,但我可以想象std::array<>
可能有用的用例(通过索引访问的成员)。
评论中建议std::vector<>
也可以使用。这是真的,标准保证成员位于连续的位置,但它们可能不是对象的本地(在std::array<>
它们是对象的本地)。
推荐阅读
- amazon-web-services - 如何查看 AWS 中每个实例的上个月 (RDS) 成本?
- php - 离线时提供 HTML 应用程序
- java - PrimeFaces 8.0 DefaultStreamedContent.builder().stream() 要求 SerializableSupplier
- javascript - 在 jQuery 中是否有任何类似于 on('click' 复选框启用事件的方法?
- ios - 如何使用 Swift 将 Int 的数组值转换为 Double
- angularjs - AngularJs filter for few values doesn't work
- c# - 无法在 wpf 中的 ContentPresenter 上显示线条形状
- python - Blockcypher-python UnicodeError(“标签太长”)
- python - 如何在 HTML 烧瓶中实现下拉多选?
- algorithm - 比较选择排序中平均情况和最坏情况交换的数量