我有一个非虚拟的最终类,它只声明了相同的类型字段。
struct Vector3 final
{
float X, Y, Z;
Vector3(float x, float y, float z) : X(x), Y(y), Z(z)
{
}
float Sum()
{
return X + Y + Z;
}
};
将此类实例的指针重新解释为浮点数组是否安全?
int main(int argc, const char *argv[])
{
Vector3 v(10, 20, 30);
Vector3 *pV = &v;
float *ff = reinterpret_cast<float*>(pV);
std::cout << ff[0] << std::endl << ff[1] << std::endl << ff[2] << std::endl;
char c;
std::cin >> c;
return 0;
}
答案 0 :(得分:6)
不,它不是 - 数据成员之间可能存在填充。
答案 1 :(得分:1)
这是安全的,但要注意breaking strict aliasing!
在C ++ 11术语中,你的结构是Standard Layout,因此可以通过reinterpret_cast
将其强制转换为第一个成员:
§9.2.20班级成员[class.mem]
指向标准布局结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单位),反之亦然。
随后的浮点数在内存中是连续的,就像数组一样。
为什么不提供operator[]
?
答案 2 :(得分:0)
通常,在便携式C ++中,没有;因为系统(编译器,运行时等)可以自由订购,并且空间结构/类成员可以随意使用。例如,要在CPU字边界上对齐成员。
如果您控制用于构建项目的编译器,则可以躲开它。如果您使用的是VC,则需要使用#pragma pack
:http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx