c ++ final非虚拟类是否被重新解释为数组安全使用?

时间:2014-01-10 19:30:42

标签: c++ arrays pointers c++11 reinterpret-cast

我有一个非虚拟的最终类,它只声明了相同的类型字段。

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;
}

3 个答案:

答案 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 packhttp://msdn.microsoft.com/en-us/library/2e70t5y1.aspx