我对reinterpret_cast和static_cast的适用性有点困惑。根据我所读到的,一般规则是当类型可以在编译时解释时使用静态强制转换,因此是静态这个词。这也是c++编译器内部用于隐式类型转换的类型转换。
reinterpret_cast适用于以下两种情况:
将整数类型转换为指针类型,反之亦然
将一种指针类型转换为另一种。我得到的一般想法是,这是不可移植的,应该避免。
我有点困惑的地方是我需要的一种用法,我从C调用c++, C代码需要保持c++对象,所以基本上它持有一个void*。在void *和Class类型之间应该使用什么类型转换?
我已经看到使用static_cast和reinterpret_cast?虽然从我所读到的似乎静态更好,因为强制转换可以在编译时发生?虽然它说使用reinterpret_cast从一种指针类型转换为另一种?
reinterpret_cast的含义不是由c++标准定义的。因此,理论上reinterpret_cast可能导致程序崩溃。在实践中,编译器试图做你所期望的事情,也就是解释你传入的二进制位,就好像它们是你要强制转换的类型一样。如果你知道你将要使用的编译器对reinterpret_cast做了什么,你就可以使用它,但是说它是可移植的是在撒谎。
对于您所描述的情况,以及您可能会考虑reinterpret_cast的大多数情况,您可以使用static_cast或其他替代方法。在其他事情中,标准有这样说你可以期待static_cast(§5.2.9):
类型为“指向cv void的指针”的右值可以显式转换为指向对象类型的指针。一个类型为pointer to object的值转换为" pointer to cv void "并返回到原始指针类型将有其原始值。
因此,对于您的用例,标准化委员会显然希望您使用static_cast。
首先你有一些特定类型的数据,比如这里的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
or
float y = *(float*)&(x);
//this could be used in c and cpp
BRIEF:这意味着相同的内存被用作不同的类型。所以你可以像上面那样将浮点数的二进制表示形式转换为int类型。例如,0x80000000为-0(尾数和指数为空,但符号msb为1。这也适用于双打和长双打。
优化:我认为reinterpret_cast会在许多编译器中进行优化,而c-casting是由指针算术进行的(值必须复制到内存中,因为指针不能指向cpu-寄存器)。
注意:在这两种情况下,您都应该在强制转换之前将强制转换的值保存在变量中!这个宏可以帮助:
#define asvar(x) ({decltype(x) __tmp__ = (x); __tmp__; })
reinterpret_cast的含义不是由c++标准定义的。因此,理论上reinterpret_cast可能导致程序崩溃。在实践中,编译器试图做你所期望的事情,也就是解释你传入的二进制位,就好像它们是你要强制转换的类型一样。如果你知道你将要使用的编译器对reinterpret_cast做了什么,你就可以使用它,但是说它是可移植的是在撒谎。
对于您所描述的情况,以及您可能会考虑reinterpret_cast的大多数情况,您可以使用static_cast或其他替代方法。在其他事情中,标准有这样说你可以期待static_cast(§5.2.9):
类型为“指向cv void的指针”的右值可以显式转换为指向对象类型的指针。一个类型为pointer to object的值转换为" pointer to cv void "并返回到原始指针类型将有其原始值。
因此,对于您的用例,标准化委员会显然希望您使用static_cast。
c++标准保证了以下内容:
指向void*和来自void*的Static_casting指针将保留地址。也就是说,下面的a、b、c都指向同一个地址:
int* a = new int();
void* b = static_cast<void*>(a);
int* c = static_cast<int*>(b);
Reinterpret_cast只保证如果将一个指针强制转换为不同的类型,然后将其重新转换为原始类型,则得到原始值。下面是:
int* a = new int();
void* b = reinterpret_cast<void*>(a);
int* c = reinterpret_cast<int*>(b);
A和c包含相同的值,但b的值未指定。(在实践中,它通常包含与a和c相同的地址,但标准中没有指定,而且在具有更复杂内存系统的机器上可能不是这样。)
对于void*和void*之间的强制转换,应该优先使用static_cast。