我知道C ++中的 reinterpret_cast 可以这样使用:
float a = 0;
int b = *reinterpret_cast<int*>(&a);
但为什么不能直接施展呢?
float a = 0;
int b = reinterpret_cast<int>(a);
error: invalid cast from type 'float' to type 'int'
答案 0 :(得分:35)
所有reinterpret_cast
都允许您以不同的方式读取您传递的内存。你给它一个内存位置,你要求它读取内存,就好像它是你要求的那样。这就是为什么它只能用于指针和引用。
我们以此代码为例:
#include <iostream>
int main()
{
float a = 12;
int b = *reinterpret_cast<int*>(&a);
std::cout << b;
}
所以要将这行代码分解为更多细节*reinterpret_cast<int*>(&a);
:
a
reinterpret_cast
到int*
int*
a
int
现在,当我运行此项时,我得到1094713344
,其原因是12,因为使用IEEE的float
在二进制中表示为0100 0001 0100 0000 0000 0000 0000 0000
。现在取这个二进制文件并将其读作unsigned int
,然后最终得到1094713344
。
这就是为什么reinterpret_cast
被认为是非常危险的原因以及为什么不应该在这种情况下使用它。
只有当指针指向内存并且需要以某种方式读取内存并且您知道可以以这种方式读取内存时,才应该使用它。
答案 1 :(得分:10)
在你给出的情况下你不能reinterpret_cast,因为reinterpret_cast只接受一个int转换为指针,反之亦然,并遵循其他类似的规则。
这些规则有摘要:http://en.cppreference.com/w/cpp/language/reinterpret_cast
答案 2 :(得分:4)
为什么不能直接投射?
我认为这是一个纯粹的设计决策,要使 C ++比C 更安全。
reinterpret_cast
非常危险,因为它可能涉及type aliasing,这是undefined behavior的简短方法。当您使用C ++强制转换时,您与编译器签订合同“我知道,我在做什么”。所以,所有这些长操作符名称,尖括号,类型指针类型的转换告诉你:“等等,不要这样做。也许你的代码设计有问题!”。
此外,并非所有C ++编译器都允许类型别名(通过转换或联合实现)。
答案 3 :(得分:2)
使用reinterpret_cast
,您可以将指针类型强制转换为任何其他指针类型
你可以将float
指针强制转换为int
指针:
float *a = new int(0);
int* b = reinterpret_cast<int*>(a);
答案 4 :(得分:2)
在第二种情况下,它不是从值a
到b
的强制转换。实际上,这只是一种转换。 b
不会指向x
并假装它指向浮点数。 Conversion构造一个int类型的新值,并为其赋值a
。
有几种方法可以在C ++中正确地进行这种转换。
一个是像往常一样使用静态演员。这是推荐的解决方案:
int b = static_cast<int>(a);
您可以通过以下方式使用reinterpret_cast。请注意,这是对位模式的重新解释,而不是与上述替代方案不同的转换:
int b = reinterpret_cast<int&>(a);
您还可以使用C样式演员:
int b = (int)a;
您还可以使用C ++函数样式转换:
int b = int(a);
您也可以获得隐式对话,尽管它可能会生成警告:
int b = a;
在这种特殊情况下,建议使用静态强制转换,但至少不要使用隐式对话,也不要使用C ++中的C样式。