江陰網(wǎng)站制作智能營銷系統(tǒng)開發(fā)

🌈 個人主頁:Zfox_
🔥 系列專欄:C++從入門到精通

目錄
- 一: 🚀 C語言中的類型轉(zhuǎn)換
- 二: 🔥 為什么C++需要四種類型轉(zhuǎn)換
- 三: 🔥 C++強制類型轉(zhuǎn)換
- 🥝 3.1 static_cast
- 🥝 3.2 reinterpret_cast
- 🥝 3.3 const_cast
- 🥝 3.4 dynamic_cast
- 四: 🔥 RTTI(了解)
- 五: 🔥 共勉
一: 🚀 C語言中的類型轉(zhuǎn)換
💢 在C語言中,如果賦值運算符左右兩側(cè)類型不同,或者形參與實參類型不匹配,或者返回值類型與接收返回值類型不一致時,就需要發(fā)生類型轉(zhuǎn)化,C語言中總共有兩種形式的類型轉(zhuǎn)換:隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。
隱式類型轉(zhuǎn)化
:編譯器在編譯階段自動進行,能轉(zhuǎn)就轉(zhuǎn),不能轉(zhuǎn)就編譯失敗。顯式類型轉(zhuǎn)化
:需要用戶自己處理。
void Test ()
{int i = 1;// 隱式類型轉(zhuǎn)換double d = i;printf("%d, %.2f\n" , i, d);int* p = &i;// 顯示的強制類型轉(zhuǎn)換int address = (int) p;printf("%x, %d\n" , p, address);
}
缺陷:
🎯 轉(zhuǎn)換的可視性比較差,所有的轉(zhuǎn)換形式都是以一種相同形式書寫,難以跟蹤錯誤的轉(zhuǎn)換。
二: 🔥 為什么C++需要四種類型轉(zhuǎn)換
🥝 C風格的轉(zhuǎn)換格式很簡單,但是有不少缺點的:
- 隱式類型轉(zhuǎn)化有些情況下可能會出問題:比如數(shù)據(jù)精度丟失
- 顯式類型轉(zhuǎn)換將所有情況混合在一起,代碼不夠清晰
💢 因此C++提出了自己的類型轉(zhuǎn)化風格,注意因為C++要兼容C語言,所以C++中還可以使用C語言的轉(zhuǎn)化風格。
三: 🔥 C++強制類型轉(zhuǎn)換
💢 標準C++為了加強類型轉(zhuǎn)換的可視性,引入了四種命名的強制類型轉(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)的類型進行轉(zhuǎn)換。
int main()
{double d = 12.34;int a = static_cast<int>(d);cout<<a<<endl;return 0;
}
- 🎯 對應(yīng)隱式類型,數(shù)據(jù)的意義沒有改變
🥝 3.2 reinterpret_cast
💢 reinterpret_cast操作符通常為操作數(shù)的位模式提供較低層次的重新解釋,用于將一種類型轉(zhuǎn)換為另一種不同的類型。
💢 reinterpret_ cast任何指針都可以轉(zhuǎn)換成其它類型的指針,T必須是一個指針、 引用、算術(shù)類型、指向函數(shù)的指針或指向一個類成員的指針。任何指針都可以轉(zhuǎn)換成其它類型的指針,不安全的轉(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;
}
- 🎯 對應(yīng)強制類型,數(shù)據(jù)的意義已經(jīng)發(fā)生改變
🥝 3.3 const_cast
💢 const_cast最常用的用途就是刪除變量的const屬性,方便賦值。
void Test ()
{const int a = 2;int* p = const_cast< int*>(&a);*p = 3;cout << a <<endl;
}
- 🎯 對應(yīng)強制類型轉(zhuǎn)換中的
有風險
的去掉const屬性 -
💢 注意此時代碼中的a值仍然是2,原因是因為內(nèi)存中的a值確實被更改為了3,但是由于編譯器的優(yōu)化,把常量存到了寄存器中,此時讀取a的值仍然是從寄存器中讀取。
🎯 解決方法:加上 volatile 后每次讀取就會直接去內(nèi)存中讀取
void Test ()
{volatile const int a = 2;int* p = const_cast< int*>(&a);*p = 3;cout << a <<endl;
}
const_cast 不能去除變量的常量性,只能用來去除指向常數(shù)對象的指針或引用的常量性,且去除常量性的對象必須為指針或引用。
🥝 3.4 dynamic_cast
💢 dynamic_cast用于將一個父類對象的指針/引用轉(zhuǎn)換為子類對象的指針或引用(動態(tài)轉(zhuǎn)換)。
向上轉(zhuǎn)換:子類對象指針/引用
->父類指針/引用
(不需要轉(zhuǎn)換,賦值兼容規(guī)則)
向下轉(zhuǎn)換:父類對象指針/引用
->子類指針/引用
((會出現(xiàn)越界訪問) 用dynamic_cast轉(zhuǎn)型是安全的)
注意:
1. dynamic_cast只能用于父類含有虛函數(shù)的類。
2. dynamic_cast會先檢查是否能轉(zhuǎn)換成功,能成功則轉(zhuǎn)換,不能則返回0。
class A
{
public :virtual void f(){}
};class B : public A
{};void fun (A* pa)
{// dynamic_cast會先檢查是否能轉(zhuǎn)換成功,能成功則轉(zhuǎn)換,不能則返回B* pb1 = static_cast<B*>(pa);B* pb2 = dynamic_cast<B*>(pa);cout<<"pb1:" <<pb1<< endl;cout<<"pb2:" <<pb2<< endl;
}int main ()
{A a;B b;fun(&a);fun(&b);return 0;
}
注意:
- 強制類型轉(zhuǎn)換關(guān)閉或掛起了正常的類型檢查,每次使用強制類型轉(zhuǎn)換前,程序員應(yīng)該仔細考慮是否還有其他不同的方法達到同一目的,如果非強制類型轉(zhuǎn)換不可,則應(yīng)限制強制轉(zhuǎn)換值的作用域,以減少發(fā)生錯誤的機會。強烈建議:避免使用強制類型轉(zhuǎn)換。
四: 🔥 RTTI(了解)
🎯 RTTI:Run-time Type identification的簡稱,即:運行時類型識別。
💢 C++通過以下方式來支持RTTI:
- typeid運算符
- dynamic_cast運算符
- decltype
五: 🔥 共勉
以上就是我對 【【C++】 類型轉(zhuǎn)換
的理解,覺得這篇博客對你有幫助的,可以點贊收藏關(guān)注支持一波~😉