Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类与结构的内存布局如何_C++_C_Class_Struct_Language Lawyer - Fatal编程技术网

C++ 类与结构的内存布局如何

C++ 类与结构的内存布局如何,c++,c,class,struct,language-lawyer,C++,C,Class,Struct,Language Lawyer,我来自C编程,在C编程中,结构中的数据首先使用顶部变量,然后是第二个、第三个,依此类推 我现在正在用C++编程,而我正在使用一个类。我基本上想达到同样的效果,但是我也想要GET/SET方法,也可能需要其他方法(我也想尝试用C++风格来做,并且可以学到一些新的东西)。 是否有保证,例如,公共变量首先在内存中,然后是私有变量 是否有保证,例如,公共变量将在 内存是私有变量吗 不,这样的保证不是C++11标准,[class.mem]/14: 具有相同访问权限的(非联合)类的非静态数据成员 控制权的分配

我来自C编程,在C编程中,结构中的数据首先使用顶部变量,然后是第二个、第三个,依此类推

我现在正在用C++编程,而我正在使用一个类。我基本上想达到同样的效果,但是我也想要GET/SET方法,也可能需要其他方法(我也想尝试用C++风格来做,并且可以学到一些新的东西)。 是否有保证,例如,公共变量首先在内存中,然后是私有变量

是否有保证,例如,公共变量将在 内存是私有变量吗

不,这样的保证不是C++11标准,[class.mem]/14:

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

所以

仅保证对于类型为
a
的给定对象

  • i
    的地址小于
    j
  • j
    的地址小于
    str
请注意,类键
struct
class
在布局方面没有任何区别:它们唯一的区别是仅在编译时存在的访问权限



它只表示顺序,但不表示第一个变量实际开始 在“第一个地址”?让我们假设一个没有继承的类

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

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

[类别]/7:

标准布局类是指:

  • 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员
  • 没有虚拟函数(10.3)和虚拟基类(10.1)
  • 对所有非静态数据成员具有相同的访问控制(第11条)
  • 没有非标准布局基类
  • 在最派生的类中没有非静态数据成员,并且最多有一个基类具有非静态数据成员,或者没有基类 具有非静态数据成员的类,以及
  • 没有与第一个非静态数据成员类型相同的基类。110
110)这可确保具有相同类类型且属于同一最派生对象的两个子对象不存在 在同一地址分配(5.10)


第一件事:类< /COD>和 Stult在C++中非常不同,唯一的区别是在类< /C>中第一个访问说明符之前的所有成员都被认为是私有的,而在 Stult中它们是公共的。 是否有保证,例如,公共变量首先在内存中,然后是私有变量

没有这样的保证。当没有继承时,内存将按照在同一访问组中声明类成员的顺序分配给它们。由编译器决定是将公共成员变量置于私有/受保护变量之前,还是将其置于私有/受保护变量之前。与C一样,C++可以在类成员之间添加填充。 继承使事情更加复杂,因为基类的数据成员也需要放在派生类中。除此之外,还有虚拟继承和多重继承,以及复杂的规则

我基本上想要实现相同的[layout],但我也想要get/set方法,也可能需要其他方法


如果您使类的所有数据成员都是私有的,并且添加访问器成员函数(即C++从其他语言调用的方法),那么您将达到这个效果。经验法则是将热变量放在顶部。类和结构之间的布局绝对没有区别。所以,如果我先定义公共变量,它们将在内存中处于第一位?我假设我可以通过这种方式访问私有成员?为什么你需要知道数据在内存中是如何排列的?我知道这很好理解,但在实践中,如果你需要知道的话,在很多情况下,这可能表明你做错了……如果类是“简单的”(可能满足Columbo提到的标准布局类标准),并且数组是一个字符数组(不是int数组或类似的数组),那么这应该是可能的。你基本上是在执行二进制(反)序列化,这并不少见。所以如果我有公共变量和私有变量,我不能假设它们是按顺序排列的?如果我只有公共或私人地址呢?那么他们的地址确实在增加。正如引用所说,它只说明顺序,而不是第一个变量实际上从“第一个地址”开始?让我们假设一个没有继承的类。@Phataas还添加了需求列表。这给了我很好的洞察力,并且解释得很好!我曾考虑使用该类从指向数组开头的指针强制转换到此类,但现在我不确定这是否可行,因为类中的访问器成员函数和其他可能的填充等占用了内存?

struct A
{
    int i, j;
    std::string str;

private:

    float f;

protected:

    double d;
};