const_cast
主要用於刪除變量的const屬性,便於賦值
const int a = 2;
int* p = const_cast<int*>(&a );
*p = 3;
reinterpret_cast
僅僅是重新解釋類型,沒有二進制的轉化,主要用於:
- 指針,整數之間的互相轉化
- 在指針類型(尤其是函數指針)之間進行轉換
int *ip;
char *pc = reinterpret_cast<char*>(ip);
依賴於硬件,移植性很差,很少使用。
static_cast
- 主要用於基本類型的轉換,如int轉double等
- 基類和子類之間轉換:其中子類指針轉換成父類指針是安全的;但父類指針轉換成子類指針是不安全的。(基類和子類之間的動態類型轉換建議用dynamic_cast)
- 把空指針轉換成目標類型的空指針
PS:
相比於C語言的直接轉換,static_cast具有編譯時期的類型檢查機制,同時可讀性好,便於查錯。
B,C類型無關
C* pc = (C*) new B;//可以編譯通過
C* pc = static_cast<C*>(new B); //編譯錯誤!!!
dynamic_cast
有條件轉換,動態類型轉換,運行時類型安全檢查(轉換失敗返回NULL):
安全的基類和子類之間轉換.
向上轉型:子類對象指針->父類指針/引用(不需要轉換)
向下轉型:父類對象指針->子類指針/引用(用dynamic_cast轉型是安全的)dynamic_cast只能用於含有虛函數的類
- 相同基類不同子類之間的交叉轉換,但結果是NULL。dynamic_cast會先檢查是否能轉換成功,能成功則轉換,不能則返回NULL
爲何使用dynamic_cast轉換類指針時,需要虛函數呢。
Dynamic_cast轉換是在運行時進行轉換,運行時轉換就需要知道類對象的信息(繼承關係等)。
如何在運行時獲取到這個信息——虛函數表。
C++對象模型中,對象實例最前面的就是虛函數表指針,
通過這個指針可以獲取到該類對象的所有虛函數,包括父類的。
因爲派生類會繼承基類的虛函數表,所以通過這個虛函數表,我們就可以知道該類對象的父類,在轉換的時候就可以用來判斷對象有無繼承關係。
所以虛函數對於正確的基類指針轉換爲子類指針是非常重要的。
DerivedClass *pd1 = static_cast<DerivedClass *>(pb);
//子類->父類,靜態類型轉換,正確但不推薦
DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb);
//子類->父類,動態類型轉換,正確
BaseClass* pb2 = new BaseClass();
DerivedClass *pd21 = static_cast<DerivedClass *>(pb2);
//父類->子類,靜態類型轉換,危險!訪問子類m_szName成員越界
DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2);
//父類->子類,動態類型轉換,安全的。結果是NULL