C風格的強制類型轉換很簡單,均用 Type b = (Type)a 形式轉換。C++風格的類型轉換提供了4種類型轉換操作符來應對不同場合的應用,如下表:
轉換類型操作符 | 作用 |
const_cast | 去掉類型的const或volatile屬性 |
static_cast | 無條件轉換,靜態類型轉換 |
dynamic_cast | 有條件轉換,動態類型轉換,運行時檢查類型安全(轉換失敗返回NULL) |
reinterpret_cast | 僅重新解釋類型,但沒有進行二進制的轉換 |
1、const_cast
去掉類型的const或volatile屬性
int main() { struct T { int i; }; const T a; //a.i = 10; //直接修改const類型,編譯錯誤 T &b = const_cast<T&>(a); b.i = 10; return 0; }
2、static_cast
類似C風格的強制轉換,進行無條件轉換,靜態類型轉換:
1)基類和子類之間的轉換:其中子類指針轉換為父類指針是安全的,但父類指針轉換為子類指針是不安全的(基類和子類之間的動態類型轉換建議用dynamic_cast)。
2)基本數據類型轉換,enum,struct,int,char,float等。static_cast不能進行無關類型(如非基類和子類)指針之間的轉換。
3)把任何類型的表達式轉換成void類型。
4)static_cast不能去掉類型的const、volatile屬性(用const_cast)。
int main() { int n = 6; double d = static_cast<double>(n); //基本類型轉換 int *pn = &n; double *d = static_cast<double*>(&n); //無關類型轉換,編譯錯誤 void *p = static_cast<void*>(pn); return 0; }
3、dynamic_cast
有條件轉換,動態類型轉換,運行時檢查類型安全(轉換失敗返回NULL):
1)安全的基類和子類之間的轉換。
2)必須有虛函數。
3)相同基類不同子類之間的交叉轉換,但結果返回NULL。
class Base { public: int _i; virtual void foo() {}; //基類必須有虛函數。保持多態特性才能使用dynamic_cast }; class Sub : public Base { public: char *_name[100]; void Bar() {}; }; int main() { Base* pb = new Sub(); Sub* ps1 = static_cast<Sub*>(pb); //子類->父類,靜態類型轉換,正確但不推薦 Sub* ps2 = dynamic_cast<Sub*>(pb); //子類->父類,動態類型轉換,正確 Base* pb2 = new Base(); Sub* ps21 = static_cast<Sub*>(pb2); //父類->子類,靜態類型轉換,危險!訪問子類_name成員越界 Sub* ps22 = dynamic_cast<Sub*>(pb2);//父類->子類,動態類型轉換,安全,但結果為NULL return 0; }
4、reinterpret_cast
僅重新解釋類型,但沒有進行二進制的轉換:
1)轉換的類型必須是一個指針,應用、算術類型、函數指針或者成員指針。
2)在比特級別上進行轉換,可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還可以得到原先的指針值)。但不能將非32bit的實例轉成指針。
3) 最普通的用途就是在函數指針類型之間進行轉換。
4) 很難保證移植性。
int doSomething() { return 0; }; int main() { typedef void(*FuncPtr)(); //FuncPtr is 一個指向函數的指針,該函數沒有參數,返回值類型為 void FuncPtr funcPtrArray[10]; //10個FuncPtrs指針的數組 讓我們假設你希望(因為某些莫名其妙的原因)把一個指向下面函數的指針存入funcPtrArray數組: funcPtrArray[0] = &doSomething;// 編譯錯誤!類型不匹配,reinterpret_cast可以讓編譯器以你的方法去看待它們:funcPtrArray funcPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething); //不同函數指針類型之間進行轉換 return 0; }
總結
去const屬性用const_cast
基本類型轉換用static_cast
多態類之間的類型轉換用dynamic_cast
不同類型的指針類型轉換用reinterpret_cast