免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
C++標(biāo)準(zhǔn)轉(zhuǎn)換運(yùn)算符reinterpret_cast

reinterpret_cast <new_type> (expression)

reinterpret_cast運(yùn)算符是用來(lái)處理無(wú)關(guān)類型之間的轉(zhuǎn)換;它會(huì)產(chǎn)生一個(gè)新的值,這個(gè)值會(huì)有與原始參數(shù)(expressoin)有完全相同的比特位。

什么是無(wú)關(guān)類型?我沒(méi)有弄清楚,沒(méi)有找到好的文檔來(lái)說(shuō)明類型之間到底都有些什么關(guān)系(除了類的繼承以外)。后半句倒是看出了reinterpret_cast的字面意思:重新解釋(類型的比特位)。我們真的可以隨意將一個(gè)類型值的比特位交給另一個(gè)類型作為它的值嗎?其實(shí)不然。

IBM的C++指南里倒是明確告訴了我們r(jià)einterpret_cast可以,或者說(shuō)應(yīng)該在什么地方用來(lái)作為轉(zhuǎn)換運(yùn)算符:

  • 從指針類型到一個(gè)足夠大的整數(shù)類型
  • 從整數(shù)類型或者枚舉類型到指針類型
  • 從一個(gè)指向函數(shù)的指針到另一個(gè)不同類型的指向函數(shù)的指針
  • 從一個(gè)指向?qū)ο蟮闹羔樀搅硪粋€(gè)不同類型的指向?qū)ο蟮闹羔?/li>
  • 從一個(gè)指向類函數(shù)成員的指針到另一個(gè)指向不同類型的函數(shù)成員的指針
  • 從一個(gè)指向類數(shù)據(jù)成員的指針到另一個(gè)指向不同類型的數(shù)據(jù)成員的指針

不過(guò)我在Xcode中測(cè)試了一下,事實(shí)上reinterpret_cast的使用并不局限在上邊所說(shuō)的幾項(xiàng)的,任何類型的指針之間都可以互相轉(zhuǎn)換,都不會(huì)得到編譯錯(cuò)誤。上述列出的幾項(xiàng),可能 是Linux下reinterpret_cast使用的限制,也可能是IBM推薦我們使用reinterpret_cast的方式

所以總結(jié)來(lái)說(shuō):reinterpret_cast用在任意指針(或引用)類型之間的轉(zhuǎn)換;以及指針與足夠大的整數(shù)類型之間的轉(zhuǎn)換;從整數(shù)類型(包括枚舉類型)到指針類型,無(wú)視大小。

(所謂"足夠大的整數(shù)類型",取決于操作系統(tǒng)的參數(shù),如果是32位的操作系統(tǒng),就需要整形(int)以上的;如果是64位的操作系統(tǒng),則至少需要長(zhǎng)整形(long)。具體大小可以通過(guò)sizeof運(yùn)算符來(lái)查看)。

reinterpret_cast有何作用

從上邊對(duì)reinterpret_cast介紹,可以感覺(jué)出reinterpret_cast是個(gè)很強(qiáng)大的運(yùn)算符,因?yàn)?span id="fu8ihs5fyo3" class="accentuation" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-weight: bold; text-decoration: underline; line-height: 1.5; ">它可以無(wú)視種族隔離,隨便搞。但就像生物的準(zhǔn)則,不符合自然規(guī)律的隨意雜交只會(huì)得到不能長(zhǎng)久生存的物種。隨意在不同類型之間使用reinterpret_cast,也之后造成程序的破壞和不能使用。

比如下邊的代碼
typedef int (*FunctionPointer)(int); 
int value = 21; 
FunctionPointer funcP; 
funcP = reinterpret_cast<FunctionPointer> (&value); 
funcP(value);

我先用typedef定義了一個(gè)指向函數(shù)的指針類型,所指向的函數(shù)接受一個(gè)int類型作為參數(shù)。然后我用reinterpret_cast將一個(gè)整型的地址轉(zhuǎn)換成該函數(shù)類型并賦值給了相應(yīng)的變量。最后,我還用該整形變量作為參數(shù)交給了指向函數(shù)的指針變量。

這個(gè)過(guò)程編譯器都成功的編譯通過(guò),不過(guò)一旦運(yùn)行我們就會(huì)得到"EXC_BAD_ACCESS"的運(yùn)行錯(cuò)誤,因?yàn)槲覀兺ㄟ^(guò)funcP所指的地址找到的并不是函數(shù)入口。

由此可知,reinterpret_cast雖然看似強(qiáng)大,作用卻沒(méi)有那么廣。IBM的C++指南、C++之父Bjarne Stroustrup的FAQ網(wǎng)頁(yè)MSDN的Visual C++也都指出:錯(cuò)誤的使用reinterpret_cast很容易導(dǎo)致程序的不安全,只有將轉(zhuǎn)換后的類型值轉(zhuǎn)換回到其原始類型,這樣才是正確使用reinterpret_cast方式。

這樣說(shuō)起來(lái),reinterpret_cast轉(zhuǎn)換成其它類型的目的只是臨時(shí)的隱藏自己的什么(做個(gè)臥底?),要真想使用那個(gè)值,還是需要讓其露出真面目才行。那到底它在C++中有其何存在的價(jià)值呢?

MSDN的Visual C++ Developer Center 給出了它的使用價(jià)值:用來(lái)輔助哈希函數(shù)。下邊是MSNDN上的例子:

                // expre_reinterpret_cast_Operator.cpp// compile with: /EHsc#include <iostream>// Returns a hash code based on an addressunsigned 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位的系統(tǒng),可能需要將unsigned int改成 unsigned long才能運(yùn)行。            

這段代碼適合體現(xiàn)哈希的思想,暫時(shí)不做深究,但至少看Hash函數(shù)里面的操作,也能體會(huì)到,對(duì)整數(shù)的操作顯然要對(duì)地址操作更方便。在集合中存放整形數(shù)值,也要比存放地址更具有擴(kuò)展性(當(dāng)然如果存void *擴(kuò)展性也是一樣很高的),唯一損失的可能就是存取的時(shí)候整形和地址的轉(zhuǎn)換(這完全可以忽略不計(jì))。

不過(guò)可讀性可能就不高,所以在這種情況下使用的時(shí)候,就可以用typedef來(lái)定義個(gè)指針類型:
typedef unsigned int PointerType;

這樣不是更棒,當(dāng)我們?cè)?4位機(jī)器上運(yùn)行的時(shí)候,只要改成:
typedef unsigned long PointerType;

當(dāng)reinterpret_cast面對(duì)const

IBM的C++指南指出:reinterpret_cast不能像const_cast那樣去除const修飾符。 這是什么意思呢?代碼還是最直觀的表述:

int main() {	typedef void (*FunctionPointer)(int);	int value = 21;	const int* pointer = &value;		//int * pointer_r = reinterpret_cast<int*> (pointer); 	// Error: reinterpret_cast from type 'const int*' to type 'int*' casts away constness		FunctionPointer funcP = reinterpret_cast<FunctionPointer> (pointer);}

例子里,我們像前面const_cast一篇舉到的例子那樣,希望將指向const的指針用運(yùn)算符轉(zhuǎn)換成非指向const的指針。但是當(dāng)實(shí)用reinterpret_cast的時(shí)候,編譯器直接報(bào)錯(cuò)組織了該過(guò)程。這就體現(xiàn)出了const_cast的獨(dú)特之處。

但是,例子中還有一個(gè)轉(zhuǎn)換是將指向const int的指針付給指向函數(shù)的指針,編譯順利通過(guò)編譯,當(dāng)然結(jié)果也會(huì)跟前面的例子一樣是無(wú)意義的。

如果我們換一種角度來(lái)看,這似乎也是合理的。因?yàn)?br style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">const int* p = &value;
int * const q = &value;

這兩個(gè)語(yǔ)句的含義是不同的,前者是"所指內(nèi)容不可變",后者則是"指向的地址不可變"(具體參考此處)。因此指向函數(shù)的指針默認(rèn)應(yīng)該就帶有"所指內(nèi)容不可變"的特性。

畢竟函數(shù)在編譯之后,其操作過(guò)程就固定在那里了,我們唯一能做的就是傳遞一些參數(shù)給指針,而無(wú)法改變已編譯函數(shù)的過(guò)程。所以從這個(gè)角度來(lái)想,上邊例子使用reinterpret_cast從const int * 到FunctionPointer轉(zhuǎn)換就變得合理了,因?yàn)樗](méi)有去除const限定

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
第一部分 基礎(chǔ)語(yǔ)言之四表達(dá)式
C++ 標(biāo)準(zhǔn)轉(zhuǎn)換運(yùn)算符static_cast
c++中的關(guān)鍵字const_cast,dynamic_cast,reinterpret_cast,static_cast 強(qiáng)制類型轉(zhuǎn)換運(yùn)算符
C++類型轉(zhuǎn)換
C++中類型轉(zhuǎn)換
C++中四種類型轉(zhuǎn)換方式
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服