教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢(xún)/投訴熱線(xiàn):400-618-4000

C++培訓(xùn)之如何使用c++中的類(lèi)型轉(zhuǎn)換

更新時(shí)間:2016年08月26日16時(shí)14分 來(lái)源:傳智播客C++培訓(xùn)學(xué)院 瀏覽次數(shù):

    關(guān)于C風(fēng)格的強(qiáng)制類(lèi)型轉(zhuǎn)換是程序猿用的最多的一種轉(zhuǎn)換方式, 不管什么類(lèi)型的轉(zhuǎn)換統(tǒng)統(tǒng)都是TYTE b = (TYPE)a。但是眾所周知C++程序中對(duì)類(lèi)型的檢測(cè)非常嚴(yán)格,如果類(lèi)型轉(zhuǎn)換過(guò)程中使用C風(fēng)格的類(lèi)型轉(zhuǎn)換就容易出現(xiàn)一些問(wèn)題。所以今天傳智播客C/C++專(zhuān)家在這里給大家介紹一下C++風(fēng)格的類(lèi)型轉(zhuǎn)換的幾種轉(zhuǎn)換操作符以及使用場(chǎng)合。
C++風(fēng)格的類(lèi)型轉(zhuǎn)換提供了4種類(lèi)型轉(zhuǎn)換操作符:
const_cast,static_cast,dynamic_cast,reinterpret_cast
4種類(lèi)型轉(zhuǎn)換的格式,如:TYPE B = static_cast(TYPE)(a)。
  • const_cast
    • 去掉類(lèi)型的const或volatile屬性。
struct SA
{
int i;
};
const SA ra;
//ra.i = 10; //直接修改const類(lèi)型,編譯錯(cuò)誤
SA &rb = const_cast<SA&>(ra);
rb.i =10;
  • static_cast
類(lèi)似于C風(fēng)格的強(qiáng)制轉(zhuǎn)換。主要應(yīng)用場(chǎng)景:
  • 基類(lèi)和子類(lèi)之間轉(zhuǎn)換:其中子類(lèi)指針轉(zhuǎn)換成父類(lèi)指針是安全的;但父類(lèi)指針轉(zhuǎn)換成子類(lèi)指針是不安全的。(基類(lèi)和子類(lèi)之間的動(dòng)態(tài)類(lèi)型轉(zhuǎn)換建議用dynamic_cast)
  • 基本數(shù)據(jù)類(lèi)型轉(zhuǎn)換。
enum, struct, int, char, float等。static_cast不能進(jìn)行無(wú)關(guān)類(lèi)型(如非基類(lèi)和子類(lèi))指針之間的轉(zhuǎn)換。
  • 把空指針轉(zhuǎn)換成目標(biāo)類(lèi)型的空指針。
  • 把任何類(lèi)型的表達(dá)式轉(zhuǎn)換成void類(lèi)型。
  • static_cast不能去掉類(lèi)型的const、volitale屬性(用const_cast)。
 int n =6;
// 基本類(lèi)型轉(zhuǎn)換
double d = static_cast<double>(n);
int*pn =&n;
// 無(wú)關(guān)類(lèi)型指針轉(zhuǎn)換,編譯錯(cuò)誤
double*d = static_cast<double*>(&n)
// 任意類(lèi)型轉(zhuǎn)換成void類(lèi)型
void*p = static_cast<void*>(pn);
  • dynamic_cast
有條件轉(zhuǎn)換、動(dòng)態(tài)類(lèi)型轉(zhuǎn)換,運(yùn)行時(shí)會(huì)進(jìn)行類(lèi)型安全檢查(轉(zhuǎn)換失敗返回NULL):
  • 安全的基類(lèi)和子類(lèi)之間轉(zhuǎn)換。
  • 必須要有虛函數(shù)。
  • 相同基類(lèi)不同子類(lèi)之間的交叉轉(zhuǎn)換。但結(jié)果是NULL。
class ItcastClass
{
public:
int m_iNum;
// 基類(lèi)必須有虛函數(shù)。保持多臺(tái)特性才能使用dynamic_cast
virtual void foo(){};
};
 
class HeiMaClass: public ItcastClass
{
public:
char*m_szName[100];
void bar(){};
};
 
ItcastClass* pb =new HeiMaClass();
// 子類(lèi)->父類(lèi),靜態(tài)類(lèi)型轉(zhuǎn)換,正確但不推薦
HeiMaClass *pd1 = static_cast<HeiMaClass *>(pb);
// 子類(lèi)->父類(lèi),動(dòng)態(tài)類(lèi)型轉(zhuǎn)換,正確
HeiMaClass *pd2 = dynamic_cast<HeiMaClass *>(pb);
ItcastClass* pb2 =new ItcastClass();
// 父類(lèi)->子類(lèi),靜態(tài)類(lèi)型轉(zhuǎn)換,危險(xiǎn)!訪(fǎng)問(wèn)子類(lèi)m_szName成
 員越界
HeiMaClass *pd21 = static_cast<HeiMaClass *>(pb2);
// 父類(lèi)->子類(lèi),動(dòng)態(tài)類(lèi)型轉(zhuǎn)換,安全的。結(jié)果是NULL
HeiMaClass *pd22 = dynamic_cast<HeiMaClass *>(pb2);
  • reinterpret_cast
僅僅重新解釋類(lèi)型,但沒(méi)有進(jìn)行二進(jìn)制的轉(zhuǎn)換:
  • 轉(zhuǎn)換的類(lèi)型必須是一個(gè)指針、引用、算術(shù)類(lèi)型、函數(shù)指針或者成員指針。
  • 在比特位級(jí)別上進(jìn)行轉(zhuǎn)換。它可以把一個(gè)指針轉(zhuǎn)換成一個(gè)整數(shù),也可以把一個(gè)整數(shù)轉(zhuǎn)換成一個(gè)指針(先把一個(gè)指針轉(zhuǎn)換成一個(gè)整數(shù),在把該整數(shù)轉(zhuǎn)換成原類(lèi)型的指針,還可以得到原先的指針值)。但不能將非32bit的實(shí)例轉(zhuǎn)成指針。
  • 最普通的用途就是在函數(shù)指針類(lèi)型之間進(jìn)行轉(zhuǎn)換。
  • 很難保證移植性。
int doSomething(){return0;};
// FuncPtr  是一個(gè)指向函數(shù)的指針,該函數(shù)沒(méi)有參數(shù),返回
值類(lèi)型為 void
typedef void(*FuncPtr)();
// 10個(gè)FuncPtrs指針的數(shù)組 讓我們假設(shè)你希望(因?yàn)槟承┠?br /> 名其妙的原因)把一個(gè)指向下面函數(shù)的指針存
入funcPtrArray數(shù)組:
FuncPtr funcPtrArray[10];
// 編譯錯(cuò)誤!類(lèi)型不匹配,reinterpret_cast可以讓編譯器以你
的方法去看待它們:funcPtrArray
funcPtrArray[0] =&doSomething;
//不同函數(shù)指針類(lèi)型之間進(jìn)行轉(zhuǎn)換
funcPtrArray[0]=reinterpret_cast<FuncPtr>(&doSomething);
最后傳智播客C/C++專(zhuān)家再為大家總結(jié)一下以上四種類(lèi)型轉(zhuǎn)換符的使用場(chǎng)景:
  • 去const屬性用const_cast。
  • 基本類(lèi)型轉(zhuǎn)換用static_cast。
  • 多態(tài)類(lèi)之間的類(lèi)型轉(zhuǎn)換用daynamic_cast。
  • 不同類(lèi)型的指針類(lèi)型轉(zhuǎn)換用reinterpret_cast。
今天的內(nèi)容就到這里, 祝大家學(xué)習(xí)愉快!

 本文版權(quán)歸傳智播客C++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客C/C++培訓(xùn)學(xué)院
首發(fā):http://oisangadgets.com/c/ 
0 分享到:
和我們?cè)诰€(xiàn)交談!