在一个类中,私有成员是在公共成员的单独内存中分配的,还是按照定义的顺序分配的所有成员?
例如,
class A {
private:
int a1;
int a2:3;
public:
int z;
int a3:2;
int a4:5;
private:
int a5:2;
}
Run Code Online (Sandbox Code Playgroud)
是a1,a2和a5凑钱进行内存分配或者是单纯a1,a2,a3,a4,a5?
如果发生夜总会,可能会在比特字段的情况下改变班级的大小.
具体标准参考(强调我的):
C++ 03 9.2 [class.mem]/12:
声明没有插入访问说明符的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址.由访问说明符分隔的非静态数据成员的分配顺序未指定(11.1).实施对齐要求可能导致两个相邻成员不能立即分配; 因此,可能需要空间来管理虚拟功能(10.3)和虚拟基类(10.1).
N3376(C++ 11草案的第一篇文章)9.2 [class.mem]/13:
(非联合)类的非静态数据成员与同一接入控制(第11)被分配,使得后来构件具有类对象内的较高地址.具有不同访问控制的非静态数据成员的分配顺序是未指定的.实施对齐要求可能导致两个相邻成员不能立即分配; 因此,可能需要空间来管理虚拟功能(10.3)和虚拟基类(10.1).
N3376 9.6 [class.bit]/1:
[...]类对象中位域的分配是实现定义的.位字段的对齐是实现定义的.[...]
/ 3:
[...]运算符地址&不应用于位域,因此没有指向位域的指针.[...]
C++答案:
我可能会错过一些东西,如果我这样做,请发表评论.
在C++中,基于类的类型放置了对象.在标准中,我相信只有几种类型的类可以保证成员的排序.
POD或Plain Old Data类/结构的布局与它们出现的完全相同.每个成员跟随上面声明的成员添加填充.POD类/结构是不包含任何访问修饰符的类,没有任何用户定义的构造函数/析构函数.没有静态声明的成员,并且只包含POD成员类型.
例如:
struct POD {
int x;
int y;
int z;
};
Run Code Online (Sandbox Code Playgroud)
大多数其他类型的类没有定义成员在内存中的布局方式.如果类/结构具有多个访问修饰符,则编译器可以自由地将成员放置在它认为合适的位置.同样,C++应该与Java类似,因为对于大多数不涉及使用硬件的情况,你不应该非常关心它的布局.
在删除java标记之前添加了以下内容,但仍留待将来参考.
Java答案:
Java不保证对象在内存中的布局方式,你不应该在乎.JVM可以自由地在内存中布置对象.这意味着对象甚至不必连续存储器.
现在,在我所知道的任何JVM中都没有这样做.一个更好的猜测是,它将对象与C++中的对象类似.其中每个父类成员放置在子成员之前,并且类中的每个成员根据具有所需填充的大小连续布局.
如果要检查特定对象在内存中的布局方式,可以使用反射和sun.misc.Unsafe类.