C++的四種類型轉(zhuǎn)換
一、隱式類型轉(zhuǎn)換和顯示類型轉(zhuǎn)換
當(dāng)?shù)忍?hào)兩邊的類型不同的時(shí)候、形參與實(shí)參類型不匹配的時(shí)候、返回值類型與接收返回值類型不一致時(shí),就需要發(fā)生類型轉(zhuǎn)化。
而類型轉(zhuǎn)換又分為隱式類型轉(zhuǎn)換和顯示類型轉(zhuǎn)換。
int main()
{
// 隱式類型轉(zhuǎn)換
int Ival = 1;
double Dval = Ival;
// 顯示類型轉(zhuǎn)換
int* p = &Ival;
int pi = p;// error
int pi = (int)p;
return 0;
}
隱式類型轉(zhuǎn)換是編譯器在編譯階段自動(dòng)進(jìn)行,能轉(zhuǎn)就轉(zhuǎn),不能轉(zhuǎn)就編譯失敗。
而顯示類型轉(zhuǎn)換就要我們自己處理。
二、C++的四種類型轉(zhuǎn)換
上面的兩種類型轉(zhuǎn)換是C語(yǔ)言風(fēng)格的,存在一些缺點(diǎn)。
隱式類型轉(zhuǎn)換會(huì)造成精度的丟失。
而顯示類型轉(zhuǎn)換則會(huì)導(dǎo)致轉(zhuǎn)換不清晰(不知道誰(shuí)轉(zhuǎn)化過(guò)來(lái))。
所以C++提供了規(guī)范的四種類型轉(zhuǎn)換
2.1 static_cast 相似轉(zhuǎn)化
如果想要進(jìn)行相似類型的轉(zhuǎn)換,編譯器隱式執(zhí)行的任何類型轉(zhuǎn)換都可用。
但是如果是兩個(gè)不相關(guān)的類型就不能轉(zhuǎn)換。
int main()
{
int i = 0;
double d = static_cast<int>(i);
int* p = nullptr;
int pi = static_cast<int>(p);// error
return 0;
}
2.2 reinterpret_cast 不同類型轉(zhuǎn)化
上面我們用指針類型轉(zhuǎn)化成整型出現(xiàn)錯(cuò)誤,而這種不同類型的轉(zhuǎn)換要用reinterpret_cast。
int main()
{
int i = 0;
double d = static_cast<int>(i);
int* p = nullptr;
int pi = static_cast<int>(p);// error
int pi = reinterpret_cast<int>(p);// correct
return 0;
}
2.3 const_cast 去除const屬性
使用const_cast的主要目的是為了去除一個(gè)const變量的const,方便賦值。
int main()
{
const int i = 1;
int* p = const_cast<int*>(&i);
*p = 3;
cout << i << endl;
return 0;
}
這里的結(jié)果需要注意一下:


這里是因?yàn)榫幾g器把這個(gè)變量放到了寄存器中,我們修改的是內(nèi)存中的數(shù)據(jù),不影響寄存器,我們可以加上volatile關(guān)鍵字(每次都去內(nèi)存中取)來(lái)看看:
int main()
{
volatile const int i = 1;
int* p = const_cast<int*>(&i);
*p = 3;
cout << i << endl;
return 0;
}

2.4 dynamic_cast 向下轉(zhuǎn)換
dynamic_cast用于將一個(gè)父類對(duì)象的指針/引用轉(zhuǎn)換為子類對(duì)象的指針或引用(動(dòng)態(tài)轉(zhuǎn)換)
在前面的文章【C++】繼承中講過(guò),子類對(duì)象賦值給父類 對(duì)象/指針/引用,這里有個(gè)形象的說(shuō)法叫切片或者切割,寓意把派生類中父類那部分切來(lái)賦值過(guò)去。
但是如果我們直接把父類類傳遞給子類,會(huì)不安全,因?yàn)楦割愞D(zhuǎn)給子類會(huì)多開一份空間,可能會(huì)越界訪問(wèn)。
class A
{
public:
virtual void f() {}
public:
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void fun(A* pa)
{
B* pb = (B*)pa;
pb->_a++;
pb->_b++;
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}

而加上dynamic_cast后如果轉(zhuǎn)化失敗就會(huì)返回空指針,讓我們檢查:
class A
{
public:
virtual void f() {}
public:
int _a = 0;
};
class B : public A
{
public:
int _b = 0;
};
void fun(A* pa)
{
B* pb = dynamic_cast<B*>(pa);
cout << pb << endl;
if (pb)
{
pb->_a++;
pb->_b++;
}
}
int main()
{
A a;
B b;
fun(&a);
fun(&b);
return 0;
}

但是這里要注意dynamic_cast只能用于父類含有虛函數(shù)的類
到此這篇關(guān)于C++的四種類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++類型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言超詳細(xì)分析多進(jìn)程的概念與使用
在一個(gè)項(xiàng)目中并發(fā)執(zhí)行任務(wù)時(shí)多數(shù)情況下都會(huì)選擇多線程,但有時(shí)候也會(huì)選擇多進(jìn)程,例如可以同時(shí)運(yùn)行n個(gè)記事本編輯不同文本,由一個(gè)命令跳轉(zhuǎn)到另外一個(gè)命令,或者使用不同進(jìn)程進(jìn)行協(xié)作2022-08-08
C語(yǔ)言實(shí)現(xiàn)商品管理系統(tǒng)開發(fā)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)商品管理系統(tǒng)開發(fā),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
C++?解決求兩個(gè)鏈表的第一個(gè)公共結(jié)點(diǎn)問(wèn)題
本文主要介紹了利用C++實(shí)現(xiàn)輸入兩個(gè)無(wú)環(huán)的單向鏈表時(shí),找出它們的第一個(gè)公共結(jié)點(diǎn)的問(wèn)題。文章中的示例代碼簡(jiǎn)潔易懂,感興趣的同學(xué)可以和小編一起學(xué)習(xí)一下2021-12-12
C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
嵌入式C實(shí)戰(zhàn)項(xiàng)目開發(fā)技巧:對(duì)一個(gè)有規(guī)律的數(shù)組表進(jìn)行位移操作的方法
今天小編就為大家分享一篇關(guān)于嵌入式C實(shí)戰(zhàn)項(xiàng)目開發(fā)技巧:對(duì)一個(gè)有規(guī)律的數(shù)組表進(jìn)行位移操作的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12
C語(yǔ)言順序表實(shí)現(xiàn)代碼排錯(cuò)
這篇文章主要介紹了C語(yǔ)言順序表實(shí)現(xiàn)方法,大家參考使用吧2013-12-12

