C++為什麼非要引入那幾種類型轉換?
技術標籤:c++
大家好,我是程式喵,今天我們放鬆下,看一些型別轉換的知識點!
眾所周知C++關於型別轉換引入了四種方式:
- static_cast
- const_cast
- dynamic_cast
- reinterpret_cast
-
為什麼要引入這幾種型別轉換,它與C語言中的強制型別轉換有什麼區別?
-
這四種類型轉換分別應用在什麼場景?
C++為什麼要引入這幾種強制型別轉換?
我們都知道C++完全相容C語言,C語言的轉換方式很簡單,可以在任意型別之間轉換,但這也恰恰是缺點,因為極其不安全,可能不經意間將指向const物件的指標轉換成非const物件的指標,可能將基類物件指標轉成了派生類物件的指標,這種轉換很容易出bug,需要嚴格審查程式碼才能消除這種隱患,但是C這種轉換方式不利於我們審查程式碼,且程式執行時也可能會出bug。
而C++引入的這幾種型別轉換可以完美的解決上述問題,不同場景下不同需求使用不同的型別轉換方式,同時有利於程式碼審查。
下面詳細介紹這四種類型轉換的使用場景:
static_cast
使用方式:
#include <iostream> 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<int>(f); cout << "i " << i << endl; int *pi = static_cast<int *>(&f); // error invalid static_cast from type ‘float*’ to type ‘int*’ Derive d; d.Func(); Base *b = static_cast<Base *>(&d); b->Func(); return 0; }
使用場景:基本資料型別之間的轉換使用,例如float轉int,int轉char等,在有型別指標和void*之間轉換使用,子類物件指標轉換成父類物件指標也可以使用static_cast。
非多型型別轉換一般都使用static_cast,而且最好把所有的隱式型別轉換都是用static_cast進行顯示替換,不能使用static_cast在有型別指標之間進行型別轉換。
dynamic_cast
使用方式:
#include <iostream> 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<Base *>(&d); b->Func(); Derive *dd = dynamic_cast<Derive *>(b); dd->Func(); return 0; }
使用場景:用於將父類的指標或引用轉換為子類的指標或引用,此場景下父類必須要有虛擬函式,因為dynamic_cast是執行時檢查,檢查需要執行時資訊RTTI,而RTTI儲存在虛擬函式表中,關於虛擬函式表具體可以看我的這篇文章:面試系列之C++的物件佈局
const_cast
使用方式:
int main() {
int data = 10;
const int *cpi = &data;
int *pi = const_cast<int *>(cpi);
const int *cpii = const_cast<const int *>(pi);
return 0;
}
使用場景:用於常量指標或引用與非常量指標或引用之間的轉換,只有const_cast才可以對常量進行操作,一般都是用它來去除常量性,去除常量性是危險操作,還是要謹慎操作。
reinterpret_cast
使用方式:
int main() {
int data = 10;
int *pi = &data;
float *fpi = reinterpret_cast<float *>(pi);
return 0;
}
使用場景:沒啥場景,類似C語言中的強制型別轉換,什麼都可以轉,萬不得已不要使用,一般前三種轉換方式不能解決問題了使用這種強制型別轉換方式。