简体   繁体   English

C ++最终非虚拟类是否可以重新解释为可安全使用的数组?

[英]Is c++ final non-virtual class reinterpreted as array safe for use?

I've got a non-virtual final class that declares only same type fields. 我有一个非虚拟的最终类,它只声明相同的类型字段。

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

Is it safe to reinterpret pointer to instance of this class to array of floats? 将指向此类实例的指针重新解释为浮点数组是否安全?

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

不,不是-数据成员之间可能存在填充。

It's safe, but beware breaking strict aliasing ! 这是安全的,但请注意不要破坏严格的别名

In C++11 jargon your struct is Standard Layout , hence it's safe to cast it via reinterpret_cast to its first member: 在C ++ 11术语中,您的结构是Standard Layout ,因此通过reinterpret_cast将其reinterpret_cast为它的第一个成员是安全的:

§ 9.2.20 Class members [class.mem] 第9.2.20节班级成员[class.mem]

A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. 指向标准布局结构对象的指针(使用reinterpret_cast进行了适当的转换)指向其初始成员(如果该成员是位域,则指向其驻留的单元),反之亦然。

The subsequent floats are then contiguous in memory, just like an array. 然后,后续的浮点在内存中是连续的,就像数组一样。


Why dont you provide an operator[] ? 您为什么不提供operator[]

Generally, in portable C++, no; 通常,在可移植的C ++中,没有。 because the system (compiler, runtime, etc) is free to order and space struct/class members as it pleases. 因为系统(编译器,运行时等)可以自由订购和随意分配结构/类成员。 For example, to align members on CPU word boundaries. 例如,在CPU字边界上对齐成员。

If you control the compiler used to build the project you can get away with it. 如果您控制用于构建项目的编译器,则可以摆脱它。 If you're using VC you'll need to use #pragma pack : http://msdn.microsoft.com/en-us/library/2e70t5y1.aspx 如果您使用的是VC,则需要使用#pragma packhttp : //msdn.microsoft.com/zh-CN/library/2e70t5y1.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM