reinterpret_cast可以在任意指针之间进行互相转换,即使这些指针所指的内容是毫无关系的,也就是说一下语句,编译器是不会报错的,但是对于程序来说也是毫无意义可言的,只会造成程序崩溃:
#include <iostream> using namespace std; unsigned short Hash( void *p ) { unsigned long val = reinterpret_cast<unsigned long>( p ); return ( unsigned short )( val ^ (val >> 16)); } class Something { /* Some codes here */ }; class Otherthing { /* Some codes here */ }; int main() { typedef unsigned short (*FuncPointer)( void *) ; FuncPointer fp = Hash; //right, this is what we want int a[10]; const int* ch = a; //right, array is just like pointer char chArray[4] = {'a','b','c','d'}; fp = reinterpret_cast<FuncPointer> (ch); //no error, but does not make sense ch = reinterpret_cast<int*> (chArray); //no error cout <<hex<< *ch; //output: 64636261 //it really reinterpret the pointer Something * st = new Something(); Otherthing * ot = reinterpret_cast<Otherthing*> (st); //cast between objects with on relationship }
而以上转换,都是static_cast所不能完成的任务,也就是说把上边程序里所有的reinterpret_cast换成static_cast的话,就会立即得到编译错误,因为目标指针和原始指针之间不存在"关系"
从上边的程序,也就一下子看出来了reinterpret_cast和static_cast之间最本质的区别。
而以上转换,都是static_cast所不能完成的任务,也就是说把上边程序里所有的reinterpret_cast换成static_cast的话,就会立即得到编译错误,因为目标指针和原始指针之间不存在"关系"
从上边的程序,也就一下子看出来了reinterpret_cast和static_cast之间最本质的区别。
对于static_cast所需要的关系,"继承"绝对是其中之一,所以static_cast支持指向基类的指针和指向子类的指针之间的互相转换:
class Parents { public: virtual ~Parents(){} /*codes here*/ }; class Children : public Parents { /*codes here*/ }; int main() { Children * daughter = new Children(); Parents * mother = static_cast<Parents*> (daughter); //right, cast with polymorphism Parents * father = new Parents(); Children * son = static_cast<Children*> (father); //no error, but not safe }
但是从基类到子类的转换,用static_cast并不是安全的
最后一个例子
#include <iostream> using namespace std; class ClassA { public: virtual ~ ClassA(){}; virtual void FunctionA(){}; }; class ClassB { public: virtual void FunctionB(){}; }; class ClassC : public ClassA,public ClassB { }; int main(void) { ClassC aObject; ClassA* pA=&aObject; ClassB* pB=&aObject; ClassC* pC=&aObject; ClassA* pA2; //error pA2=static_cast<ClassA*>(pB); void *pVoid=static_cast<void*>(pB); pA2=static_cast<ClassA*>(pVoid); //error pA2=pB; pA2=static_cast<ClassA*>(static_cast<ClassC*>(pB)); return 0; }