按照经验法则首先选择static_cast
或dynamic_cast
,我写了以下程序:
int main(void)
{
int i = 0;
unsigned *j = static_cast<unsigned*>(&i);
return 0;
}
但是,它甚至没有编译:
$ g++ --std=c++11 test5.cpp
test5.cpp: In function ‘int main()’:
test5.cpp:4:44: error: invalid static_cast from type ‘int*’ to type ‘unsigned int*’
unsigned *j = static_cast<unsigned*>(&i);
^
为什么这是错的?这种情况的正确演员是什么?
答案 0 :(得分:7)
您可static_cast
从int
到unsigned
执行适当的转化。但你拥有的是一个指针;此指针指向要解释为int
的内存区域。取消引用指针会产生int
的值。 static_cast
will not convert between pointers to unrelated types
int i = 0;
int* ip = &i;
int j = *ip; // treat the region pointed to as an int
要在取消引用下将内存视为unsigned
,您需要重新解释内存;这是reinterpret_cast
的作用。
int i = 0;
int* ip = &i;
unsigned j = *reinterpret_cast<unsigned*>(ip); // treat the region pointed to as unsigned
但是,你不应该这样做。 reinterpret_cast
完全按照它所说的做法:将内存重新解释为不同的类型。如果位模式与该类型的预期不匹配,则结果将与static_cast<unsigned>
执行的转换不同。例如,在没有使用2的补码表示有符号整数的系统中就是这种情况。
正确的方法是取消引用int*
然后static_cast<unsigned>
的结果:
int i = 0;
int* ip = &i;
unsigned j = static_cast<unsigned>(*ip); // treat the region pointed to as int
// then convert the int to unsigned
总结一下:static_cast
将执行整数转换,但不会将内存区域重新解释为不同的类型。这是reinterpret_cast
的用途。
答案 1 :(得分:2)
你必须使用:
unsigned *j = static_cast<unsigned*>(static_cast<void*>(&i));
这是您在第5点阅读here的内容,或只是使用:reinterpret_cast:
int i = 0;
unsigned *j = reinterpret_cast<unsigned*>(&i);
经常使用cast-s程序员而不是如下所示使用联合:
union {
int n;
unsigned char bt[4];
} data;
data.n = i;
data.bt[3] = 0xff;
正如在评论中所说,使用union进行强制转换是未定义的行为 - 即使大多数编译器都支持它:您可以在此处阅读更多内容:Is using an union in place of a cast well defined?和Is using an union in place of a cast well defined?