强制转换操作符reinterpret_cast是一个非常有趣的操作符。我们常见的强制转换操作符static_cast在强制转换的时候是有一些限制的。例如,我们不能把int这样的系统内置类型转换成char*这样的指针类型,不能进行像int*和char*这样的指针类型之间的转换。但是reinterpret_cast却没有这方面的限制。它似乎是无所无能的,虽然我没有把所有的可能性都实验一遍,但是上述的两种情况在用reinterpret_cast进行转换的时候编译器是可以通过的。当然,编译通过不代表结果就正确。
下面这段程序作为一个引子。它说明了char*类型的指针可以直接初始化string对象。
#include <iostream>
#include <string>
using std::string;
int main()
{
char ca[] = "program";
char *cp = ca;
string str = cp;
return 0;
}
可以看见,编译是正确的。
可以看到,string对象str的值确实就是字符串“program”。
再看下面这段程序
#include <iostream>
#include <string>
using std::string;
int main()
{
int ia = 9;
int *ip = &ia;
char *cp = reinterpret_cast<char*>(ip);//强制把ip付给cp
string str = cp;
return 0;
}
我们看到,编译是没有问题的。
cp也确实获得了ip的地址。
但是,当cp初始化string对象str时出现了问题,如果用输出流输出str,那么结果是什么都输出不了。这是因为虽然我们定义的cp是一个char类型的指针变量,但是cp实际上指向的是一个int类型的变量。在这个程序中我们能够较为容易的判断出cp实际指向的对象,可是如果是在一些比较大的程序中,cp的强制转换语句与str初始化语句离得非常远,甚至是在两个文件中时,这样的错误将是非常隐蔽的,及其难以处理。这个例子很好的说明了强制转换时多么的危险。所以程序员应该避免使用强制类型转换,不用强制类型转换也能写出非常好的程序。
另外还有一点想说。如果把上面程序的第九行改为
char *cp = static_cast<char*>(ip);
程序在编译的时候就无法通过。
int ia;
char *cp = reinterpret_cast<char*>(ia);
这样的语句也是可以通过编译的,而对于static_cast操作符,上面的代码就不能通过编译了。这也看出reinterpret_cast操作符的强大了。