C++中的類型轉換 static_cast、dynamic_cast、const_cast、reinterpret_cast

類型轉換可以讓我們將一種類型的變量當做另外一種類型來使用,常見的類型轉換方式包括

C風格的類型轉換

轉換格式爲:(類型)變量

int a = 10;
double b = a;
float c = b;
Base* base = (Base*)new Derived();

C++自帶的類型轉換

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast

爲什麼有了C風格的類型轉換方式後C++還添加這四種類型轉換方式呢?

因爲C風格的類型轉換可以在任意類型之間轉換,比如你可以把一個指向const對象的指針轉換成指向非const對象的指針,把一個指向基類對象的指針轉換成指向一個派生類對象的指針,這兩種轉換之間的差別是巨大的,但是傳統的c語言風格的類型轉換沒有區分這些。還有一個缺點就是,c風格的轉換不容易查找,他由一個括號加上一個標識符組成,而這樣的東西在c++程序裏一大堆。

static_cast

類似與C風格的無條件靜態類型轉換

1、基類和子類之間的轉換,其中:子類->基類是安全的,但是基類->子類是不安全的,建議使用dynamic_cast進行運行時判斷進行基類轉子類。

2、基本數據類型之間的轉換,int, char, float,注意不可以進行無關類型指針的轉換。

3、轉換空指針爲任何類型的空指針

Base* base1 = static_cast<Base*>(new Derived());	
Derived* base2 = static_cast<Derived*>(new Base());	 //基類->子類,有風險,不推薦使用

double num = static_cast<double>('a');	//char->double
// double* ptr = static_cast<double*>(new int(10));	錯誤,無關類型的指針轉換,轉換無效
	
double* ptr = static_cast<double*>(nullptr);	//空指針->任意類型的空指針

dynamic_cast

動態轉換主要是用於類的層次間、基類子類間轉換,具有檢驗功能,在無法進行轉換時返回nullptr。如果轉換的是引用,失敗時會拋出std::base_cast異常。可以通過返回值進行判斷是否成功轉換。

Base* base = dynamic_cast<Base*>(new Derived());		//成功
if (base == nullptr) {
	std::cout << "derived -> base 失敗" << std::endl;
}

Derived* derived = dynamic_cast<Derived*>(new Base());	 //失敗
if (derived == nullptr) {
	std::cout << "base -> derived 失敗" << std::endl;
}

返回失敗

const_cast

用於移除、添加變量的const屬性,注意C++中其他的三類轉換都沒有移除const屬性的能力,對於const_cast主要用來對頂層、底層的const進行轉換。爲什麼不可以對變量的const進行修改呢?因爲沒有意義。

int i = 10;
const int* p = &i;
const int* ci = const_cast<const int*>(p);
//*ci = 20; 提示錯誤,表達式必須是可修改的左值
int* c = const_cast<int*>(p);
*c = 20;

reinterpret_cast

re重新的意思,interpret解讀、翻譯的意思,顧名思義將數據重新按照另外一種類型進行解讀,一般很少用到,不清楚自己在操作什麼數據時,請謹慎使用。比如將四個字符當做當做一個浮點數進行處理。

char ch[4] = { 'a', 'b', 'c', 'd' };
float* f = reinterpret_cast<float*>(ch);	//四個字符共四個字節正好當做一個浮點數來處理(不嚴謹,具體根據各個平臺浮點數字節大小可能不一樣)

std::cout << *f << std::endl;

輸出

 本質上C++中的四種類型轉換都是語法糖,所有能做的C風格轉換也可以做到。但是使用C++中的類型轉換,可以讓我們更好的追蹤到我們的項目裏面的哪裏有用到類型轉換,這是C風格轉換所不具有的優勢的。

更多參考:

https://stackoverflow.com/questions/332030/when-should-static-cast-dynamic-cast-const-cast-and-reinterpret-cast-be-used

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章