一个类与结构的内存布局如何

我来自C编程,其中结构中的数据首先是top变量,然后是第二个,第三个,依此类推。

我现在用C ++编程,而我正在使用类。 我基本上想要实现相同的目标,但我也想要获取/设置方法,也可能需要其他方法(我也想尝试以C ++方式实现它,并且可能会学到新东西)。

是否有保证,例如公共变量将首先在内存中,然后是私有变量?

是否有保证,例如公共变量将首先在内存中,然后是私有变量?

不, 没有做出这样的保证 – C ++ 11标准,[class.mem] / 14:

分配具有相同访问控制 (第11条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。 具有不同访问控制的非静态数据成员的分配顺序未指定 (11)。

所以

struct A { int i, j; std::string str; private: float f; protected: double d; }; 

只保证对于给定的A类对象,

  • i的地址小于j
  • j的地址小于str

请注意,类键structclass在布局方面没有区别:它们唯一的区别是只在编译时存在的访问权限。


它只说顺序,但不是第一个变量实际上从“第一个地址”开始? 让我们假设一个没有inheritance的类。

是的,但仅适用于标准布局类 。 类必须满足一行要求才能成为标准布局类,其中之一是所有成员都具有相同的访问控制。
引用C ++ 14(同样适用于C ++ 11,但措辞更为间接),[class.mem] / 19:

如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同。 否则,其地址与其第一个基类子对象的地址(如果有)相同。 [ 注意 :因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐。 – 结束说明 ]

[类] / 7:

标准布局类是一个类:

  • 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
  • 没有虚函数(10.3),也没有虚基类(10.1),
  • 对所有非静态数据成员具有相同的访问控制(第11条),
  • 没有非标准布局基类,
  • 或者在大多数派生类中没有非静态数据成员,并且最多只有一个具有非静态数据成员的基类,或者没有具有非静态数据成员的基类,并且
  • 没有与第一个非静态数据成员相同类型的基类。 110

110)这确保具有相同类类型并且属于相同的最大派生对象的两个子对象不被分配在同一地址(5.10)。

首先要做的是:C ++中的classstruct非常相似 – 唯一的区别是class中第一个访问说明符之前的所有成员都被认为是私有的,而struct它们是公共的。

是否有保证,例如公共变量将首先在内存中,然后是私有变量?

没有这样的保证。 如果没有inheritance,则将按照在同一访问组中声明它们的顺序将内存分配给类成员。 由编译器决定是否应将公共成员变量置于私有/受保护变量之前,反之亦然。 像C一样,C ++可以在类成员之间添加填充。

inheritance使事情变得更复杂,因为基类的数据成员也需要放在派生类中。 最重要的是,存在虚拟inheritance和多重inheritance,具有复杂的规则。

我基本上想要实现相同的[布局],但我也想要get / set方法以及其他方法。

如果您将类的所有数据成员设为私有,并添加访问器成员函数(这就是C ++从其他语言中调用“方法”),您将实现此效果。