類型轉換的含義是經過改變一個變量的類型爲別的類型從而改變該變量的表示方式。程序員
C風格的強制轉換不安全。express
C++強制類型轉換:安全
一、static_cast:通常的轉換,用於數據類型的強制轉換,強制將一種數據類型轉換爲另外一種數據類型。函數
int a = 98; char c = static_cast<char>(a); cout << c << endl;// b
基礎數據類型指針,對象指針不可轉換。測試
//基礎數據類型指針 int* p = NULL; char* sp = static_cast<char*>(p);//無效 //對象指針 Building* building = NULL; Animal* ani = static_cast<Animal*>(building);//無效
能夠轉換具備繼承關係的指針或者引用ui
//父類指針轉成子類指針 Animal* ani = NULL; Cat* cat = static_cast<Cat*>(ani); //子類指針轉成父類指針 Cat* soncat = NULL; Animal* anifather = static_cast<Animal*>(soncat); //還有具備繼承關係的指針或者引用 Animal aniobj; Animal& aniref = aniobj; Cat& cat = static_cast<Cat&>(aniref); Cat catobj; Cat& catref = catobj; Animal& anifather2 = static_cast<Animal&>(catref);
二、dynamic_cast<type_id> (expression), 轉換具備繼承關係的指針或者引用,在轉換前會進行對象類型檢查,而且
只能由子類型轉成基類型極可能失敗。指針
其餘三種都是編譯時完成的,dynamic_cast是運行時處理的,運行時要進行類型檢查。code
不能用於內置的基本數據類型的強制轉換。對象
int a = 10; char c = dynamic_cast<char>(a);//無效
dynamic_cast轉換若是成功的話返回的是指向類的指針或引用,轉換失敗的話則會返回NULL。繼承
使用dynamic_cast進行轉換的,基類中必定要有虛函數,不然編譯不經過。
B中須要檢測有虛函數的緣由:類中存在虛函數,就說明它有想要讓基類指針或引用指向派生類對象的狀況,此時轉換纔有意義。這是因爲運行時類型檢查須要運行時類型信息,而這個信息存儲在類的虛函數表中,只有定義了虛函數的類纔有虛函數表。
在類的轉換時,在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是同樣的。在進行下行轉換時,dynamic_cast具備類型檢查的功能,比static_cast更安全。
向上轉換,即爲子類指針指向父類指針(通常不會出問題),內存大轉小;向下轉換,即將父類指針轉化子類指針,不安全。 向下轉換的成功與否還與將要轉換的類型有關,即要轉換的指針指向的對象的實際類型與轉換之後的對象類型必定要相同,不然轉換失敗。
在C++中,編譯期的類型轉換有可能會在運行時出現錯誤,特別是涉及到類對象的指針或引用操做時,更容易產生錯誤。Dynamic_cast操做符則能夠在運行期對可能產生問題的類型轉換進行測試。
//非繼承關係的指針 Animal* ani = NULL; Building* building = dynamic_cast<Building*>(ani);//報錯 //具備繼承關係指針 Animal* ani = NULL; Cat* cat = dynamic_cast<Cat*>(ani);//報錯 緣由在於 dynamic作類型安全檢查 Cat* cat = NULL; Animal* ani = dynamic_cast<Animal*>(cat);
三、 const_cast:const限定符一般被用來限定變量,用於表示該變量的值不能被修改,而const_cast則正是用於強制去掉這種不能被修改的常數特性,但須要特別注意的是const_cast不是用於去除變量的常量性,而是去除指向常數對象的指針或引用的常量性,其去除常量性的對象必須爲指針或引用。
//基礎數據類型 int a = 10; const int& b = a; //b = 10; int& c = const_cast<int&>(b); c = 20; cout << "a:" << a << endl;//20 cout << "b:" << b << endl;//20 cout << "c:" << c << endl;//20 const int a = 10; const int& pp = a; int& cc = const_cast<int&>(pp); cc = 100; //指針 增長或者去除變量的const性 const int* p = NULL; int* p2 = const_cast<int*>(p); int* p3 = NULL; const int* p4 = const_cast<const int*>(p3);
四、reinterpret_cast 用法:reinterpret_cast<type_id> (expression)
reinterpret_cast主要有三種強制轉換用途:
type-id必須是一個指針、引用、算術類型、函數指針或者成員指針。
它能夠把一個指針轉換成一個整數,也能夠把一個整數轉換成一個指針(先把一個指針轉換成一個整數,在把該整數轉換成原類型的指針,還能夠獲得原先的指針值)。
在使用reinterpret_cast強制轉換過程僅僅只是比特位的拷貝,所以在使用過程當中須要特別謹慎!
//1. 無關的指針類型均可以進行轉換 Building* building = NULL; Animal* ani = reinterpret_cast<Animal*>(building); //2. 函數指針轉換 FUNC1 func1; FUNC2 func2 = reinterpret_cast<FUNC2>(func1);