Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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++09新的C++11标准是否提供了一种“手动”完全确定对象布局的方法_C++ - Fatal编程技术网

C+中的类布局+;:为什么有时会要求会员? C++标准规定,在一个访问段内的成员变量必须按照声明的顺序排列在内存中。同时,编译器可以自由选择访问部分本身的相互顺序。这种自由使得理论上不可能链接由不同编译器创建的二进制文件。那么,严格按节排序的其余原因是什么呢?即将到来的C++09新的C++11标准是否提供了一种“手动”完全确定对象布局的方法

C+中的类布局+;:为什么有时会要求会员? C++标准规定,在一个访问段内的成员变量必须按照声明的顺序排列在内存中。同时,编译器可以自由选择访问部分本身的相互顺序。这种自由使得理论上不可能链接由不同编译器创建的二进制文件。那么,严格按节排序的其余原因是什么呢?即将到来的C++09新的C++11标准是否提供了一种“手动”完全确定对象布局的方法,c++,C++,这种自由使得理论上不可能链接由不同编译器创建的二进制文件 这是不可能的,原因有很多,结构布局是最次要的。vtables,操作员新建和删除的实现,数据类型大小 那么,严格按节排序的其余原因是什么呢 C兼容性,我想,这样,C中定义的结构与C++对于给定编译器集的方式相同。 新的C++0911标准是否提供了一种“手动”完全确定对象布局的方法 不,不超过现行标准 但是,对于没有vtable和完全私有(或公共)字段的类或结构,如果使用[u]int[8 | 16 | 32 | 64]类型,就已经可以了。除

这种自由使得理论上不可能链接由不同编译器创建的二进制文件

这是不可能的,原因有很多,结构布局是最次要的。vtables,
操作员新建
删除
的实现,数据类型大小

那么,严格按节排序的其余原因是什么呢

C兼容性,我想,这样,C中定义的结构与C++对于给定编译器集的方式相同。

新的C++0911标准是否提供了一种“手动”完全确定对象布局的方法

不,不超过现行标准


但是,对于没有vtable和完全私有(或公共)字段的
结构
,如果使用
[u]int[8 | 16 | 32 | 64]
类型,就已经可以了。除此之外,您还有什么使用案例?

编辑:恐怕我误解了您的问题

我认为这是对内存访问的优化。 例如,如果我们得到这个结构:

struct example
{
   int16 intData;
   byte  byteData;
   int32 intData;
   byte intData;
   int32 intData;
}
让我们假设这个平台中的字是32位。然后需要4个完整的单词来传递结构中的所有数据:

int16+byte=24位(此处不适合netx字段)

int32=32位(netx字段不适合此处)

字节=8位(netx字段不适合此处)

int32=32位

但如果将字段重新排列为:

struct example
{
   int16 intData;
   byte  byteData;
   byte intData;
   int32 intData;
   int32 intData;
}
然后您可以保存一次内存访问。

[编辑] 我今天学到了一些新东西!找到以下标准报价:

数据库的非静态数据成员 (非并集)未使用 干预访问说明符是 分配给以后的成员 类中较高的地址 对象分配顺序 非静态数据成员由 未指定访问说明符 (11.1). 实现一致性 需求可能会导致两个相邻的 不获分配的成员 紧接着彼此;也可能 对管理空间的要求 虚拟功能(10.3)和虚拟 基类(10.1)

有趣-我不知道为什么会有这样的自由度。继续上一个回复的剩余部分


如前所述,保留排序的原因是C兼容性,当时我想没有人想到对成员重新排序的好处,而内存布局通常是手工完成的。此外,现在被认为是“丑陋的把戏”(比如用memset将选定的成员归零,或者使用相同布局的两个结构)也很常见

该标准没有为您提供强制执行给定布局的方法,但大多数编译器提供了控制填充的措施,例如MSVC编译器上的#pragma pack


自动填充的原因是平台的可移植性:不同的体系结构有不同的对齐要求,例如,一些体系结构会抛出未对齐的INT(在当时这些都是简单的情况)。

您永远不应该链接由不同编译器创建的对象。即使您所谈论的内容发生了更改,您仍然会遇到更多问题,无法链接到其他编译器生成的文件。(对齐、命名混乱、调用约定仅命名其中的一小部分)

编译器可以自由排序访问部分的一个原因可能是,编译器可以为访问部分建立顺序:例如,地址较低的成员比地址较高的成员受到更大的保护

如果不允许这种重新排序,您将一无所获:只有POD提供了C兼容性,并提供了一种方法(使用宏
offsetof
)或允许您memcpy类/结构中成员的字节偏移量。如果定义自定义构造函数、复制构造函数、私有成员或其他内容,则类型将变为非POD。特别是,从类派生当前打破了PODness


C++1x降低了对吊舱的要求。例如,在C++1x
std::pair
中,它实际上是一个POD,尽管它提供了自己的构造函数(但必须符合某些规则)。

不,我很确定他是对的。我没有访问这里的标准来查找它,但我以前也注意到了同样的情况。它说不同访问段之间的顺序是未指定的,但是在一个段中,成员是按照声明的顺序排列的。我也很想知道你说的对,我已经更新了回复。现在我也很好奇。C++11对此进行了修订,以澄清插入的重复访问说明符(无论出于何种原因,有人可能会包括这些说明符)不会妨碍布局保证;只有当访问级别通过不同的说明符发生变化时,而不是重复以前的说明符。>除此之外,您还有什么用例?优化。通过对对象的数据成员重新排序,可以使对象变小。代码中的顺序通常反映了成员的逻辑组,因此您不希望对此进行更改。C++11对此进行了修订,以澄清插入的重复访问说明符(无论出于何种原因,有人可能包括这些说明符)不会妨碍布局保证;只有当访问级别通过不同的说明符进行更改时,才需要更改,而不是重复上一个说明符。