类与结构的内存布局如何
我来自 C 编程,其中结构体中的数据首先使用 top 变量布局,然后是第二个、第三个等等..
我现在正在用 C++ 编程,而我正在使用一个类.我基本上想要实现相同的目标,但我也想要 get/set 方法以及其他方法(我也想尝试以 C++ 风格来做,并且可以学习一些新的东西).
是否有保证,例如公共变量将首先在内存中然后是私有变量?
解决方案是否有保证,例如公共变量将是第一个内存然后是私有变量?
不,这样的保证没有做出 - C++11 标准,[class.mem]/14:
<块引用>具有相同访问权限的(非联合)类的非静态数据成员控制(第 11 条)被分配,以便后来的成员拥有更高的类对象中的地址.非静态的分配顺序未指定具有不同访问控制的数据成员 (11).
所以
结构体A{内部 i, j;std::string str;私人的:浮动 f;受保护:双d;};
仅保证对于 A
类型的给定对象,
i
的地址小于j
和j
的地址小于str
请注意,类键 struct
和 class
在布局方面没有任何区别:它们唯一的区别是仅在编译时存在的访问权限.><小时><块引用>
它只说顺序,但不说第一个变量实际开始在第一个地址"?让我们假设一个没有继承的类.
是的,但仅适用于标准布局类.要成为标准布局类,类必须满足一系列要求,其中之一是所有成员都具有相同的访问控制.
引用 C++14(同样适用于 C++11,但措辞更间接),[class.mem]/19:
如果一个标准布局类对象有任何非静态数据成员,它的address 与其第一个非静态数据的地址相同成员.否则,它的地址与它的第一个地址相同.基类子对象(如果有).[ 注意:因此可能有标准布局结构对象内的未命名填充,但不是在其开头,这是实现适当对齐所必需的.――结束注释 ]
[类]/7:
<块引用>标准布局类是这样一个类:
- 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
- 没有虚函数 (10.3) 和虚基类 (10.1),
- 对所有非静态数据成员具有相同的访问控制(第 11 条),
- 没有非标准布局的基类,
- 要么在最派生的类中没有非静态数据成员且至多一个具有非静态数据成员的基类,要么没有基类具有非静态数据成员的类,以及
- 没有与第一个非静态数据成员相同类型的基类.110
110) 这确保了具有相同类类型并且属于同一个最派生对象的两个子对象不是分配在同一地址(5.10).
I come from C programming where the data in a struct is laid out with the top variable first, then the second, third and so on..
I am now programming in C++ and I am using a class instead. I basically want to achieve the same, but I also want get/set methods and also maybe other methods (I also want to try do it in a C++ style and maye learn something new).
Is there a guarantee e.g. that the public variables will be first in memory then the private variable?
解决方案Is there a guarantee e.g. that the public variables will be first in memory then the private variable?
No, such a guarantee is not made - C++11 standard, [class.mem]/14:
Nonstatic data members of a (non-union) class with the same access control (Clause 11) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified (11).
So
struct A
{
int i, j;
std::string str;
private:
float f;
protected:
double d;
};
It is only guaranteed that, for a given object of type A
,
i
has a smaller address thanj
andj
has a smaller address thanstr
Note that the class-keys struct
and class
have no difference regarding layout whatsoever: Their only difference are access-rights which only exist at compile-time.
It only says the order, but not that the first variable actually start at the "first address"? Lets assume a class without inheritance.
Yes, but only for standard-layout classes. There is a row of requirements a class must satisfy to be a standard-layout class, one of them being that all members have the same access-control.
Quoting C++14 (the same applies for C++11, but the wording is more indirect), [class.mem]/19:
If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member. Otherwise, its address is the same as the address of its first base classsubobject (if any). [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. ― end note ]
[class]/7:
A standard-layout class is a class that:
- has no non-static data members of type non-standard-layout class (or array of such types) or reference,
- has no virtual functions (10.3) and no virtual base classes (10.1),
- has the same access control (Clause 11) for all non-static data members,
- has no non-standard-layout base classes,
- either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
- has no base classes of the same type as the first non-static data member. 110
110) This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address (5.10).
相关文章