C++中4種類型轉(zhuǎn)換的方法分享
1. C語(yǔ)言中的類型轉(zhuǎn)換
在C語(yǔ)言中,如果賦值運(yùn)算符左右兩側(cè)類型不同,或者形參與實(shí)參類型不匹配,或者返回值類型與接收返回值類型不一致時(shí),就需要發(fā)生類型轉(zhuǎn)化,C語(yǔ)言中總共有兩種形式的類型轉(zhuǎn)換:隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。
1. 隱式類型轉(zhuǎn)化:編譯器在編譯階段自動(dòng)進(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)換形式都是以一種相同形式書(shū)寫(xiě),難以跟蹤錯(cuò)誤的轉(zhuǎn)換
2. 為什么C++需要四種類型轉(zhuǎn)換
C風(fēng)格的轉(zhuǎn)換格式很簡(jiǎn)單,但是有不少缺點(diǎn)的:
1. 隱式類型轉(zhuǎn)化有些情況下可能會(huì)出問(wèn)題:比如數(shù)據(jù)精度丟失
2. 顯式類型轉(zhuǎn)換將所有情況混合在一起,代碼不夠清晰
因此C++提出了自己的類型轉(zhuǎn)化風(fēng)格,注意因?yàn)镃++要兼容C語(yǔ)言,所以C++中還可以使用C語(yǔ)言的轉(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,但它不能用于兩個(gè)不相關(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會(huì)報(bào)錯(cuò),應(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)存的可見(jiàn)性 const int a = 2; int* p = const_cast<int*>(&a); *p = 3; //因?yàn)閍是const類型的變量,所以編譯器進(jìn)行優(yōu)化直接將a值的內(nèi)容放到寄存器中 //用的時(shí)候不會(huì)從內(nèi)存中取,所以a的值是2 //防止編譯的優(yōu)化,可以使用volatile關(guān)鍵字,保持內(nèi)存的可見(jiàn)性 cout << a << endl; cout << *p << endl; }
3.4 dynamic_cast
dynamic_cast用于將一個(gè)父類對(duì)象的指針/引用轉(zhuǎn)換為子類對(duì)象的指針或引用(動(dòng)態(tài)轉(zhuǎn)換)
向上轉(zhuǎn)型:子類對(duì)象指針/引用->父類指針/引用(不需要轉(zhuǎn)換,賦值兼容規(guī)則)
向下轉(zhuǎn)型:父類對(duì)象指針/引用->子類指針/引用(用dynamic_cast轉(zhuǎn)型是安全的)
注意:
1. dynamic_cast只能用于父類含有虛函數(shù)的類
2. dynamic_cast會(huì)先檢查是否能轉(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)換是不安全的可能會(huì)存在越界訪問(wèn)的情況: //父類對(duì)象的指針或引用會(huì)給給子類的指針或引用訪問(wèn)子類的屬性就會(huì)存在越界訪問(wè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)換的時(shí)候使用用dynamic_cast,如果是父類對(duì)象的指針或引用給給子類對(duì)象的指針或引用時(shí)則轉(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)換時(shí),當(dāng)父類對(duì)象的指針或引用給給子類的指針或引用是返回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ā)生錯(cuò)誤的機(jī)會(huì)。強(qiáng)烈建議:避免使用強(qiáng)制類型轉(zhuǎn)換
到此這篇關(guān)于C++中4種類型轉(zhuǎn)換的方法分享的文章就介紹到這了,更多相關(guān)C++類型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言詳細(xì)分析不同類型數(shù)據(jù)在內(nèi)存中的存儲(chǔ)
使用編程語(yǔ)言進(jìn)行編程時(shí),需要用到各種變量來(lái)存儲(chǔ)各種信息。變量保留的是它所存儲(chǔ)的值的內(nèi)存位置。這意味著,當(dāng)您創(chuàng)建一個(gè)變量時(shí),就會(huì)在內(nèi)存中保留一些空間。您可能需要存儲(chǔ)各種數(shù)據(jù)類型的信息,操作系統(tǒng)會(huì)根據(jù)變量的數(shù)據(jù)類型,來(lái)分配內(nèi)存和決定在保留內(nèi)存中存儲(chǔ)什么2022-08-08C語(yǔ)言調(diào)用go生成的動(dòng)態(tài)庫(kù)的踩坑過(guò)程解析
這篇文章主要為大家介紹了C語(yǔ)言調(diào)用go生成的動(dòng)態(tài)庫(kù)的踩坑過(guò)程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09C++ STL入門(mén)教程(7) multimap、multiset的使用
這篇文章主要介紹了C++ STL入門(mén)教程第七篇,multimap一對(duì)多索引,multiset多元集合的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08從零學(xué)習(xí)cmake構(gòu)建系統(tǒng)
這篇文章主要為大家介紹了從零學(xué)習(xí)cmake構(gòu)建系統(tǒng)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02C++代碼實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++代碼實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06