C++類(lèi)型轉(zhuǎn)換


C++為了規(guī)范C中的類(lèi)型轉(zhuǎn)換,加強(qiáng)類(lèi)型轉(zhuǎn)換的可視性,引入了四種強(qiáng)制類(lèi)型轉(zhuǎn)換操作符:static_cast, reinterpret_cast, const_cast, dynamic_cast?
他們本質(zhì)上都是模板類(lèi)。
下面分別來(lái)介紹:
1.static_cast
它用于非多態(tài)類(lèi)型的轉(zhuǎn)換(靜態(tài)轉(zhuǎn)換),對(duì)應(yīng)于C中的隱式類(lèi)型轉(zhuǎn)換,但他不能用于兩個(gè)不相關(guān)類(lèi)型的轉(zhuǎn)換,如整形和整形指針之間的轉(zhuǎn)換,雖然二者都是四個(gè)字節(jié),但他們一個(gè)表示數(shù)據(jù),一個(gè)表示地址,類(lèi)型不相關(guān),無(wú)法進(jìn)行轉(zhuǎn)換。
該轉(zhuǎn)換在編譯時(shí)完成,和C風(fēng)格的類(lèi)型轉(zhuǎn)換相似,不過(guò)要注意下面幾點(diǎn)
不能在沒(méi)有派生關(guān)系的兩個(gè)類(lèi)類(lèi)型之間轉(zhuǎn)換
不能去除掉原有類(lèi)型的類(lèi)型修飾符,例如const,volatile,__unaligned
轉(zhuǎn)換對(duì)象時(shí)由于沒(méi)有動(dòng)態(tài)類(lèi)型檢查,所以由基類(lèi)對(duì)象轉(zhuǎn)換成派生類(lèi)對(duì)象的時(shí)候存在安全隱患
void Test()
{
? ? //C中的方式
? ? int i = 10;
? ? double d1 = i;//隱式類(lèi)型轉(zhuǎn)換
? ? //int *p = i;//無(wú)法隱式類(lèi)型轉(zhuǎn)換,只能強(qiáng)制類(lèi)型轉(zhuǎn)換
? ? int *p = (int*)i;
? ? //C++中的方式
? ? double d2 = static_cast<double>(i);
? ? //相當(dāng)于創(chuàng)建一個(gè)static_cast<double>類(lèi)型的匿名對(duì)象賦值給d2
? ? int* p2 = static_cast<int*>(i);//無(wú)法轉(zhuǎn)換,會(huì)報(bào)錯(cuò)
}

2.reinterpret_cast
einterpret的含義是重新解釋?zhuān)蓪⒁环N類(lèi)型轉(zhuǎn)換成另一種不相關(guān)類(lèi)型,對(duì)應(yīng)C中的強(qiáng)制類(lèi)型轉(zhuǎn)換,處理無(wú)法進(jìn)行隱式轉(zhuǎn)換的情況
void Test()
{
? ? int i = 10;
? ? int* p2 = reinterpret_cast<int*>(i);
}
強(qiáng)制類(lèi)型轉(zhuǎn)換有時(shí)可以很暴力的處理一些問(wèn)題?
如下例:?
對(duì)于一個(gè)帶參數(shù)的函數(shù),如何不傳參也可以調(diào)用該函數(shù)?
void Fun(int s)
{
? ? cout << s << endl;
}
typedef void(*FUNC)();
void Test()
{
? ? FUNC pf = reinterpret_cast<FUNC>(Fun);
? ? pf();
}
C中的強(qiáng)制類(lèi)型轉(zhuǎn)換也可以處理。?
雖然我們通過(guò)這種BUG的方式轉(zhuǎn)換函數(shù)指針,但是這樣的代碼是不可移植的,而且有時(shí)會(huì)產(chǎn)生不確定的結(jié)果,所以不建議這樣來(lái)用?
如此處輸出的s的值就為一個(gè)隨機(jī)值,雖然用戶(hù)在外部未傳參,但是該函數(shù)在調(diào)用時(shí)會(huì)創(chuàng)建形參,該形參未初始化,自然是隨機(jī)值?

3.const_cast
他的功能就是刪除變量的const屬性,方便再次賦值
該轉(zhuǎn)換在編譯時(shí)完成,用于解除const,volatile修飾符,只能轉(zhuǎn)換指針或者引用
void Test3()
{
? ? const int i = 10;
? ? int *p = const_cast<int*>(&i);
? ? *p = 20;
? ? cout << i << endl;
? ? cout << *p << endl;
}
此時(shí)這兩個(gè)值會(huì)分別輸出多少呢?
我們先來(lái)看下監(jiān)視窗口: