C++中4種類型轉(zhuǎn)換的方法分享
1. C語言中的類型轉(zhuǎn)換
在C語言中,如果賦值運(yùn)算符左右兩側(cè)類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發(fā)生類型轉(zhuǎn)化,C語言中總共有兩種形式的類型轉(zhuǎn)換:隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。
1. 隱式類型轉(zhuǎn)化:編譯器在編譯階段自動進(jìn)行,能轉(zhuǎn)就轉(zhuǎn),不能轉(zhuǎn)就編譯失敗
2. 顯式類型轉(zhuǎn)化:需要用戶自己處理
void Test()
{
int i = 1;
// 隱式類型轉(zhuǎn)換
double d = i;
printf("%d, %.2f\n", i, d);
int* p = &i;
// 顯示的強(qiáng)制類型轉(zhuǎn)換
int address = (int)p;
printf("%x, %d\n", p, address);
}
缺陷:
轉(zhuǎn)換的可視性比較差,所有的轉(zhuǎn)換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉(zhuǎn)換
2. 為什么C++需要四種類型轉(zhuǎn)換
C風(fēng)格的轉(zhuǎn)換格式很簡單,但是有不少缺點的:
1. 隱式類型轉(zhuǎn)化有些情況下可能會出問題:比如數(shù)據(jù)精度丟失
2. 顯式類型轉(zhuǎn)換將所有情況混合在一起,代碼不夠清晰
因此C++提出了自己的類型轉(zhuǎn)化風(fēng)格,注意因為C++要兼容C語言,所以C++中還可以使用C語言的轉(zhuǎn)化風(fēng)格。
3. C++強(qiáng)制類型轉(zhuǎn)換
標(biāo)準(zhǔn)C++為了加強(qiáng)類型轉(zhuǎn)換的可視性,引入了四種命名的強(qiáng)制類型轉(zhuǎn)換操作符:
static_cast、reinterpret_cast、const_cast、dynamic_cast
3.1 static_cast
static_cast用于非多態(tài)類型的轉(zhuǎn)換(靜態(tài)轉(zhuǎn)換),編譯器隱式執(zhí)行的任何類型轉(zhuǎn)換都可用static_cast,但它不能用于兩個不相關(guān)的類型進(jìn)行轉(zhuǎn)換
int main()
{
double d = 12.34;
int a = static_cast<int>(d);
cout << a << endl;
return 0;
}
3.2 reinterpret_cast
reinterpret_cast操作符通常為操作數(shù)的位模式提供較低層次的重新解釋,用于將一種類型轉(zhuǎn)換為另一種不同的類型
int main()
{
double d = 12.34;
int a = static_cast<int>(d);
cout << a << endl;
// 這里使用static_cast會報錯,應(yīng)該使用reinterpret_cast
//int *p = static_cast<int*>(a);
int* p = reinterpret_cast<int*>(a);
return 0;
}
3.3 const_cast
const_cast最常用的用途就是刪除變量的const屬性,方便賦值
void Test()
{
//volatile const int a = 2; //保持內(nèi)存的可見性
const int a = 2;
int* p = const_cast<int*>(&a);
*p = 3;
//因為a是const類型的變量,所以編譯器進(jìn)行優(yōu)化直接將a值的內(nèi)容放到寄存器中
//用的時候不會從內(nèi)存中取,所以a的值是2
//防止編譯的優(yōu)化,可以使用volatile關(guān)鍵字,保持內(nèi)存的可見性
cout << a << endl;
cout << *p << endl;
}
3.4 dynamic_cast
dynamic_cast用于將一個父類對象的指針/引用轉(zhuǎn)換為子類對象的指針或引用(動態(tài)轉(zhuǎn)換)
向上轉(zhuǎn)型:子類對象指針/引用->父類指針/引用(不需要轉(zhuǎn)換,賦值兼容規(guī)則)
向下轉(zhuǎn)型:父類對象指針/引用->子類指針/引用(用dynamic_cast轉(zhuǎn)型是安全的)
注意:
1. dynamic_cast只能用于父類含有虛函數(shù)的類
2. dynamic_cast會先檢查是否能轉(zhuǎn)換成功,能成功則轉(zhuǎn)換,不能則返回0
class A
{
public:
virtual void f() {}
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void fun(A* pa)
{
//直接轉(zhuǎn)換是不安全的可能會存在越界訪問的情況:
//父類對象的指針或引用會給給子類的指針或引用訪問子類的屬性就會存在越界訪問
B* bptr = (B*)pa;
bptr->_a++;
bptr->_b++;
cout << bptr->_a << endl;
cout << bptr->_b << endl;
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}運(yùn)行截圖:

解決方案:在類型轉(zhuǎn)換的時候使用用dynamic_cast,如果是父類對象的指針或引用給給子類對象的指針或引用時則轉(zhuǎn)換不成功。
class A
{
public:
virtual void f() {}
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void fun(A* pa)
{
//dynamic_cast轉(zhuǎn)換時,當(dāng)父類對象的指針或引用給給子類的指針或引用是返回0
B* bptr = dynamic_cast<B*>(pa);
if (bptr)
{
bptr->_a++;
bptr->_b++;
cout << bptr->_a << endl;
cout << bptr->_b << endl;
}
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}運(yùn)行截圖:

注意
強(qiáng)制類型轉(zhuǎn)換關(guān)閉或掛起了正常的類型檢查,每次使用強(qiáng)制類型轉(zhuǎn)換前,程序員應(yīng)該仔細(xì)考慮是否還有其他不同的方法達(dá)到同一目的,如果非強(qiáng)制類型轉(zhuǎn)換不可,則應(yīng)限制強(qiáng)制轉(zhuǎn)換值的作用域,以減少發(fā)生錯誤的機(jī)會。強(qiáng)烈建議:避免使用強(qiáng)制類型轉(zhuǎn)換
到此這篇關(guān)于C++中4種類型轉(zhuǎn)換的方法分享的文章就介紹到這了,更多相關(guān)C++類型轉(zhuǎn)換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)詳解
這篇文章主要為大家介紹了C++的靜態(tài)成員變量和靜態(tài)成員函數(shù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-12-12
VisualStudio2022提交git代碼的方法實現(xiàn)
本文主要介紹了VisualStudio2022提交git代碼的方法實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07

