我很好奇内存模型如何用于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编程的背景,我习惯于使用数组进行快速顺序内存访问,因此我很好奇当所有数据成员在任何调用上连续使用时,上述语义之一是否适合快速访问
答案 0 :(得分:4)
标准保证它们在内存中的排列顺序为
(如果您选择了他们的地址,他们将会增加)。
它不会不保证它们将位于连续内存中;但是,如果那是最理想的布局,那么它们可能会是。允许编译器在成员之间添加填充(通常这样做是为了提高访问效率(牺牲速度的空间))。如果所有成员的大小都相同,则不太可能。
注意:在它们之间引入public / private / protected会使事情变得复杂,并且可能会改变顺序。
您最好使用数组吗?
这取决于。您通常会通过索引还是通过名称访问它们?我会说99%的时间是您拥有的第一个版本更好,但是我可以想象用std::array<>
有用的用例(通过索引访问成员)。
也可以使用注释std::vector<>
中的建议。确实如此,并且该标准保证成员位于相邻位置,但它们可能不在对象本地(在std::array<>
中,它们在对象本地)。
答案 1 :(得分:1)
是的,可以保证顺序与[class.mem].19声明中的顺序相同
分配具有相同访问控制的(非联盟)类的非静态数据成员,以使稍后的成员在类对象中具有更高的地址。未指定具有不同访问控制的非静态数据成员的分配顺序。实施一致性要求可能会导致两个相邻成员不能彼此立即分配;管理虚拟功能和虚拟基类的空间要求也可能如此。
答案 2 :(得分:0)
[元答案]
我最好(为了表现)...
为什么连续分配数据成员必然会提高性能?实际上,由于double
之类的东西需要适当对齐,因此通常情况恰恰相反(这就是编译器并不总是这样做的原因)。