1. 程式人生 > >【C++】C++之型別轉換

【C++】C++之型別轉換

作者:李春港 出處:https://www.cnblogs.com/lcgbk/p/14209848.html [toc] # 一、前言 在C語言中,我們經常會對資料進行型別轉換,但都是強制性的型別裝換,自然就會引發訪問不安全的問題,可能不經意間將指向const物件的指標轉換成非const物件的指標,可能將基類物件指標轉成了派生類物件的指標,這種轉換很容易出bug,需要嚴格審查程式碼才能消除這種隱患,而且這種轉換方式不利於我們審查程式碼,且程式執行時也可能會出bug,所以C++為了提高型別裝換的安全性,關於型別轉換引入了四種方式:static_cast、const_cast、dynamic_cast、reinterpret_cast,接下來看下其四種類型裝換的應用場景。 # 二、static_cast ## 2.1 使用場景 基本資料型別之間的轉換使用,例如float轉int,int轉char等,在有型別指標和void*之間轉換使用,子類物件指標轉換成父類物件指標也可以使用static_cast。 非多型型別轉換一般都使用static_cast,而且最好把所有的隱式型別轉換都是用static_cast進行顯示替換,不能使用static_cast在有型別指標之間進行型別轉換。 ## 2.2 例項 ```cpp #include using namespace std; struct Base { virtual void Func() { cout << "Base Func \n"; } }; struct Derive : public Base { void Func() override { cout << "Derive Func \n"; } }; int main() { float f = 1.23; cout << "f " << f << endl; int i = static_cast(f); cout << "i " << i << endl; void *p; int *i_p = static_cast(p); void *pi = static_cast(&f); int *pi = static_cast(&f); // error invalid static_cast from type ‘float*’ to type ‘int*’ Derive d; d.Func(); Base *b = static_cast(&d); b->Func(); return 0; } ``` # 三、dynamic_cast ## 3.1 使用場景 用於將父類的指標或引用轉換為子類的指標或引用,此場景下父類必須要有虛擬函式(只要擁有虛擬函式就行),因為dynamic_cast是執行時檢查,檢查需要執行時資訊RTTI.如果不清楚什麼是RTTI,可以去了解下C++的RTTI機制。 ## 3.2 例項 ```cpp #include using namespace std; struct Base { virtual void Func() { cout << "Base Func \n"; } }; struct Derive : public Base { void Func() override { cout << "Derive Func \n"; } }; int main() { Derive d; d.Func(); Base *b = dynamic_cast(&d); b->Func(); Derive *dd = dynamic_cast(b); dd->Func(); return 0; } ``` # 四、const_cast ## 4.1 使用場景 用於常量指標或引用與非常量指標或引用之間的轉換,只有const_cast才可以對常量進行操作,一般都是用它來去除常量性,去除常量性是危險操作,還是要謹慎操作。 ## 4.2 例項 ```cpp int main() { int data = 10; const int *cpi = &data; int *pi = const_cast(cpi); const int *cpii = const_cast(pi); return 0; } ``` # 五、reinterpret_cast ## 5.1 使用場景 沒啥場景,類似C語言中的強制型別轉換,什麼都可以轉,萬不得已不要使用,一般前三種轉換方式不能解決問題了使用這種強制型別轉換方式。 ## 5.2 例項 ```cpp int main() { int data = 10; int *pi = &data; float *fpi = reinterpret_cast(pi); return 0; } ``` # 六、總結 | 方式 | 使用場景 | | --- | --- | | static_cast | 基本資料型別之間的轉換使用,例如float轉int,int轉char等;子類物件指標轉換成父類物件指標也可以使用static_cast;在有型別指標和void*之間轉換使用,不能使用static_cast在有型別指標之間進行型別轉換。 | | dynamic_cast | 用於將父類的指標或引用轉換為子類的指標或引用,此場景下父類必須要有虛擬函式(只要擁有虛擬函式就行)| | const_cast | 用於常量指標或引用與非常量指標或引用之間的轉換。| | reinterpret_cast | 類似C語言中的強制型別轉換,什麼都可以轉,儘量不要使用此方