reinterpret_cast運算符是用來處理無關類型之間的轉換;它會產生一個新的值,這個值會有與原始參數(expression)有徹底相同的比特位。html
什麼是無關類型?我沒有弄清楚,沒有找到好的文檔來講明類型之間到底都有些什麼關係(除了類的繼承之外)。後半句卻是看出了reinterpret_cast的字面意思:從新解釋(類型的比特位)。咱們真的能夠隨意將一個類型值的比特位交給另外一個類型做爲它的值嗎?其實否則。ios
IBM的C++指南里卻是明確告訴了咱們reinterpret_cast能夠,或者說應該在什麼地方用來轉換運算符:express
不過我在Xcode中測試了一下,事實上reinterpret_cast的使用並不侷限在上邊所說的幾項的,任何類型的指針之間均可以互相轉換,都不會獲得編譯錯誤。上述列出的幾項,可能 是Linux下reinterpret_cast使用的限制,也多是IBM推薦咱們使用reinterpret_cast的方式。安全
因此總結來講:reinterpret_cast用在任意指針(或引用)類型之間的轉換;以及指針與足夠大的整數類型之間的轉換;從整數類型(包括枚舉類型)到指針類型,無視大小。jsp
(所謂「足夠大的整數類型」,取決於操做系統的參數,若是是32位的操做系統,就須要整型(int)以上的;若是是64位的操做系統,則至少須要長整型(long)。具體大小能夠經過sizeof運算符來查看)。ide
從上邊對reinterpret_cast介紹,能夠感受出reinterpret_cast是個很強大的運算符,由於它能夠無視種族隔離,隨便搞。但就像生物的準則,不符合天然規律的隨意雜交只會獲得不能長久生存的物種。隨意在不一樣類型之間使用reinterpret_cast,也會形成程序的破壞和不能使用。函數
好比下邊的代碼測試
typedef int (*FunctionPointer)(int); int value = 21; FunctionPointer funcP; funcP = reinterpret_cast<FunctionPointer> (&value); funcP(value);
先用typedef定義一個指向函數的指針類型,所指向的函數接受一個int類型做爲參數。而後我用reinterpret_cast將一個整型的地址轉換成該函數類型並賦值給了相應的變量。最後,我還用該整型變量做爲參數交給了指向函數的指針變量。spa
這個過程編譯器都成功地編譯經過,不過一旦運行咱們就會獲得「EXC_BAD_ACCESS」的運行錯誤,由於咱們經過funcP所指的地址找到的並非函數入口。操作系統
由此可知,reinterpret_cast雖然看似強大,做用卻沒有那麼廣。IBM的C++指南、C++之父Bjarne Stroustrup的FAQ網頁和MSDN的Visual C++也都指出:錯誤的使用reinterpret_cast很容易致使程序的不安全,只有將轉換後的類型值轉換回到其原始類型,這樣纔是正確使用reinterpret_cast方式。
這樣提及來,reinterpret_cast轉換成其它類型的目的只是臨時地隱藏本身的什麼(作個臥底?),要真想使用那個值,仍是須要讓其露出真面目才行。那到底它在C++中有其怎樣存在的價值呢?
MSDN的Visual C++ Developer Center 給出了它的使用價值:用來輔助哈希函數。下邊是MSNDN上的例子:
// expre_reinterpret_cast_Operator.cpp // compile with: /EHsc #include <iostream> // Returns a hash code based on an address unsigned short Hash( void *p ) { unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); } using namespace std; int main() { int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; } //若是跟我同樣是64位的系統,可能須要將unsigned int改爲 unsigned long才能運行。
這段代碼是如何體現哈希的思想,暫時不作深究,但至少看Hash函數裏面的操做,也能體會到,對整數的操做顯然要比對地址操做更方便。在集合中存放整型數值,也要比存放地址更具備擴展性(固然若是存void *擴展性也是同樣很高的),惟一損失的可能就是存取的時候整型和地址的轉換(這徹底能夠忽略不計)。
轉自:
http://www.cnblogs.com/ider/archive/2011/07/30/cpp_cast_operator_part3.html