什么时候使用reinterpret_cast?

别来无恙 提交于 2020-02-28 06:51:38

我对reinterpret_caststatic_cast的适用性不感到困惑。 从我所读的内容中,一般规则是在编译时可以解释类型的情况下使用static强制转换,因此单词static 。 这是C ++编译器内部也用于隐式强制转换的强制转换。

reinterpret_cast适用于两种情况:

  • 将整数类型转换为指针类型,反之亦然
  • 将一种指针类型转换为另一种。 我得到的一般想法是,这是不可移植的,应该避免。

我有点困惑的是我需要的一种用法,我从C调用C ++,C代码需要保留在C ++对象上,因此基本上它包含void* 。 应该使用哪种强制转换在void *和Class类型之间进行转换?

我看过static_castreinterpret_cast用法吗? 虽然从我所读的内容来看, static似乎更好,因为强制转换可以在编译时进行? 尽管它说使用reinterpret_cast从一种指针类型转换为另一种指针类型?


#1楼

template <class outType, class inType>
outType safe_cast(inType pointer)
{
    void* temp = static_cast<void*>(pointer);
    return static_cast<outType>(temp);
}

我试图总结并使用模板编写了一个简单的安全类型转换。 请注意,此解决方案不能保证将指针强制转换为函数。


#2楼

您可以使用reinterprete_cast在编译时检查继承。
在这里看: 使用reinterpret_cast在编译时检查继承


#3楼

reinterpret_cast的一种用法是如果您想对(IEEE 754)浮点数应用按位运算。 一个例子是快速逆平方根技巧:

https://zh.wikipedia.org/wiki/Fast_inverse_square_root#Overview_of_the_code

它将float的二进制表示形式视为整数,将其右移并从常数中减去它,从而使指数减半并取反。 转换回浮点数后,将对其进行牛顿-拉夫森(Newton-Raphson)迭代,以使此近似值更加精确:

float Q_rsqrt( float number )
{
    long i;
    float x2, y;
    const float threehalfs = 1.5F;

    x2 = number * 0.5F;
    y  = number;
    i  = * ( long * ) &y;                       // evil floating point bit level hacking
    i  = 0x5f3759df - ( i >> 1 );               // what the deuce? 
    y  = * ( float * ) &i;
    y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//  y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

    return y;
}

这最初是用C编写的,因此使用C强制转换,但是类似的C ++强制转换是reinterpret_cast。


#4楼

快速解答:如果要编译,请使用static_cast ,否则请使用reinterpret_cast


#5楼

首先,您具有一些特定类型的数据,例如int:

int x = 0x7fffffff://==nan in binary representation

然后,您想访问与其他类型(例如float)相同的变量:

float y = reinterpret_cast<float&>(x);

//this could only be used in cpp, looks like a function with template-parameters

要么

float y = *(float*)&(x);

//this could be used in c and cpp

简介:这意味着将相同的内存用作不同的类型。 因此,您可以将浮点数的二进制表示形式转换为浮点数,如上述的int类型。 例如,0x80000000为-0(尾数和指数为null,但符号msb为1。这也适用于双打和长双打。

优化:我认为reinterpret_cast将在许多编译器中得到优化,而c广播是通过指针算术进行的(该值必须复制到内存中,因为指针无法指向cpu寄存器)。

注意:在这两种情况下,都应在强制转换之前将强制转换值保存在变量中! 此宏可以帮助:

#define asvar(x) ({decltype(x) __tmp__ = (x); __tmp__; })
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!