首页 > 解决方案 > 对象数据成员的 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 编程背景,并且习惯于使用数组进行快速顺序内存访问,所以我很好奇当所有数据成员在任何调用中连续使用时,是否首选上述语义之一来进行快速访问。

标签: c++performanceoopmemoryc++17

解决方案


  • 该标准保证它们将在内存中按该顺序排列
    (如果您获取它们的地址,它们会增加)。

  • 它不保证它们会在连续的内存中;但如果这是最优化的布局,那么它们可能会是。允许编译器在成员之间添加填充(它通常这样做是为了提高访问效率(为了速度而牺牲空间))。如果所有成员的大小相同,则这是不可能的。

注意:在它们之间引入 public/private/protected 会使事情复杂化并且可能会改变顺序。

你最好使用数组吗?

那要看。您通常会通过索引还是通过名称访问它们?我会说 99% 的时间你拥有的第一个版本会更好,但我可以想象std::array<>可能有用的用例(通过索引访问的成员)。

评论中建议std::vector<>也可以使用。这是真的,标准保证成员位于连续的位置,但它们可能不是对象的本地(在std::array<>它们是对象的本地)。


推荐阅读