Ami*_*mar 5 c c++ pointers structure class
考虑这两种情况:
struct customType
{
dataType1 var1;
dataType2 var2;
dataType3 var3;
} ;
customType instance1;
// Assume var1, var2 and var3 were initialized to some valid values.
customType * instance2 = &instance1;
dataType1 firstMemberInsideStruct = (dataType1)(*instance2);
Run Code Online (Sandbox Code Playgroud)
class CustomType
{
public:
dataType1 member1;
dataType2 member2;
retrunType1 memberFunction1();
private:
dataType3 member3;
dataType4 member4;
retrunType2 memberFunction2();
};
customType object;
// Assume member1, member2, member3 and member4 were initialized to some valid values.
customType *pointerToAnObject = &object ;
dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);
Run Code Online (Sandbox Code Playgroud)
是否总是安全做到这一点?
我想知道标准是否指定了任何存储顺序 -
9.0.7
标准布局类是一个类: - 没有类型为非标准布局类(或此类类型的数组)或引用的非静态数据成员, - 没有虚函数(10.3)且没有虚基类( 10.1), - 对所有非静态数据成员具有相同的访问控制(第11条), - 没有非标准布局基类, - 在最派生类中没有非静态数据成员,最多只有一个具有非静态数据成员的基类,或者没有具有非静态数据成员的基类,并且 - 没有与第一个非静态数据成员相同类型的基类.
9.2.14
分配具有相同访问控制(第11条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址.未指定具有不同访问控制的非静态数据成员的分配顺序(11).实施对齐要求可能导致两个相邻成员不能立即分配; 因此,可能需要空间来管理虚拟功能(10.3)和虚拟基类(10.1).
9.2.20
指向标准布局结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然.[注意:因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐. - 结束说明]
C99和C ++对此有所不同。
C99标准保证结构的字段按声明的顺序排列在内存中,并且两个相同结构的字段具有相同的偏移量。见这个问题为C99标准的相关章节。总结一下:第一个字段的偏移量指定为零,但此后的偏移量未由标准指定。这是为了允许C编译器调整每个字段的偏移量,以便该字段将满足体系结构的任何内存对齐要求。因为这与实现有关,所以C提供了使用offsetof宏确定每个字段的偏移量的标准方法。
C ++仅对纯旧数据(POD)提供此保证。不是普通旧数据的C ++类不能这样对待。当类使用多重继承,具有非公共字段或成员或包含虚拟成员时,该标准为C ++编译器在组织类时提供了很大的自由度。
这对您的示例意味着什么:
dataType1 firstMemberInsideStruct = (dataType1)(*instance2);
Run Code Online (Sandbox Code Playgroud)
仅当 dataType1,dataType2和dataType3是纯旧数据时,此行才可以。如果其中任何一个都不存在,则customType结构可能没有琐碎的构造函数(或析构函数),并且这种假设可能不成立。
dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);
Run Code Online (Sandbox Code Playgroud)
无论此行是不是安全dataType1,dataType2以及dataType3是POD,因为CustomType类有私有的实例变量。这使得它不是 POD类,因此您不能假定其第一个实例变量将以特定方式排序。