C++ 中 class 私有成员的内存顺序是否得到保证?
Is order in memory guaranteed for class private members in C++?
class my_class_t {
private:
uint64_t field1;
uint64_t field2;
};
C++ 标准在内存中保证 field1
和 field2
的顺序吗?
更新。回答说field2
是,但是&field2
可能不等于&field1 + 1
。如何保证field2
紧跟在field1
之后?
是的,订单有保证。
field1
的地址必须与 my_class_t
的实例地址相同。 field2
比 field1
有一个 "higher" 地址,因为 field1
地址上的 reinterpret_cast
获得的 unsigned char*
指针的正指针算术将最终到达field2
.
占用的内存
但请注意,尝试通过指向 field1
的指针算术 "reach" field2
的行为是 undefined.
至于确保成员之间没有填充,您不能在可移植的 C++ 中做到这一点。但是您可以使用数组类型:
class my_class_t {
private:
uint64_t fields[2];
};
哪个会保证这一点。然后你可以使用指针算法到达成员。
它们保证彼此之间的地址递增 ([class.mem]/13):
Nonstatic data members of a (non-union) class with the same access
control (Clause [class.access]) are allocated so that later members
have higher addresses within a class object.
注意我用粗体标记的文字。虽然当它们都是私有时保证 field2
在 field1
之后,但如果它们具有不同的访问控制则不必如此。当然,中间填充始终是一种选择。
但是如果你想强制不存在填充,并且它们是同一类型,数组就可以做到:
uint64_t field[2];
这也使得 &field[0] + 1
定义明确,因为这些对象现在显然是同一数组的成员。
当访问限定符不介入时,对象在内存中的顺序将与声明的顺序相同。
class my_class_t {
private:
uint64_t field1;
uint64_t field2;
};
C++ 标准在内存中保证 field1
和 field2
的顺序吗?
更新。回答说field2
是,但是&field2
可能不等于&field1 + 1
。如何保证field2
紧跟在field1
之后?
是的,订单有保证。
field1
的地址必须与 my_class_t
的实例地址相同。 field2
比 field1
有一个 "higher" 地址,因为 field1
地址上的 reinterpret_cast
获得的 unsigned char*
指针的正指针算术将最终到达field2
.
但请注意,尝试通过指向 field1
的指针算术 "reach" field2
的行为是 undefined.
至于确保成员之间没有填充,您不能在可移植的 C++ 中做到这一点。但是您可以使用数组类型:
class my_class_t {
private:
uint64_t fields[2];
};
哪个会保证这一点。然后你可以使用指针算法到达成员。
它们保证彼此之间的地址递增 ([class.mem]/13):
Nonstatic data members of a (non-union) class with the same access control (Clause [class.access]) are allocated so that later members have higher addresses within a class object.
注意我用粗体标记的文字。虽然当它们都是私有时保证 field2
在 field1
之后,但如果它们具有不同的访问控制则不必如此。当然,中间填充始终是一种选择。
但是如果你想强制不存在填充,并且它们是同一类型,数组就可以做到:
uint64_t field[2];
这也使得 &field[0] + 1
定义明确,因为这些对象现在显然是同一数组的成员。
当访问限定符不介入时,对象在内存中的顺序将与声明的顺序相同。