【C++】C++之類型轉換
作者:李春港
出處://www.cnblogs.com/lcgbk/p/14209848.html
一、前言
在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 實例
#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;
void *p;
int *i_p = static_cast<int *>(p);
void *pi = static_cast<void *>(&f);
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;
}
三、dynamic_cast
3.1 使用場景
用於將父類的指針或引用轉換為子類的指針或引用,此場景下父類必須要有虛函數(只要擁有虛函數就行),因為dynamic_cast是運行時檢查,檢查需要運行時信息RTTI.如果不清楚什麼是RTTI,可以去了解下C++的RTTI機制。
3.2 實例
#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;
}
四、const_cast
4.1 使用場景
用於常量指針或引用與非常量指針或引用之間的轉換,只有const_cast才可以對常量進行操作,一般都是用它來去除常量性,去除常量性是危險操作,還是要謹慎操作。
4.2 實例
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;
}
五、reinterpret_cast
5.1 使用場景
沒啥場景,類似C語言中的強制類型轉換,什麼都可以轉,萬不得已不要使用,一般前三種轉換方式不能解決問題了使用這種強制類型轉換方式。
5.2 實例
int main() {
int data = 10;
int *pi = &data;
float *fpi = reinterpret_cast<float *>(pi);
return 0;
}
六、總結
方式 | 使用場景 |
---|---|
static_cast | 基本數據類型之間的轉換使用,例如float轉int,int轉char等;子類對象指針轉換成父類對象指針也可以使用static_cast;在有類型指針和void*之間轉換使用,不能使用static_cast在有類型指針之間進行類型轉換。 |
dynamic_cast | 用於將父類的指針或引用轉換為子類的指針或引用,此場景下父類必須要有虛函數(只要擁有虛函數就行) |
const_cast | 用於常量指針或引用與非常量指針或引用之間的轉換。 |
reinterpret_cast | 類似C語言中的強制類型轉換,什麼都可以轉,盡量不要使用此方式。 |