一文帶你深入了解C++中的類型轉(zhuǎn)換
C語言中的類型轉(zhuǎn)換
在C語言中,如果賦值運(yùn)算符左右兩側(cè)類型不同,或者形參與實(shí)參類型不匹配,或者返回值類型與接收返回值類型不一致時(shí),就需要發(fā)生類型轉(zhuǎn)化,C語言中總共有兩種形式的類型轉(zhuǎn)換:隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。
1.隱式類型轉(zhuǎn)化:編譯器在編譯階段自動(dòng)進(jìn)行,能轉(zhuǎn)就轉(zhuǎn),不能轉(zhuǎn)就編譯失敗
2.顯式類型轉(zhuǎn)化:需要用戶自己處理
3.缺陷:轉(zhuǎn)換的可視性比較差,所有的轉(zhuǎn)換形式都是以一種相同形式書寫,難以跟蹤錯(cuò)誤的轉(zhuǎn)換
int main() { int i = 1; // 隱式類型轉(zhuǎn)換(意義相近的類型) double d = i; printf("%d, %.2f\n", i, d); int* p = &i; // 顯示的強(qiáng)制類型轉(zhuǎn)換(意義不相近的類型,值轉(zhuǎn)換后有意義) int address = (int)p; printf("%x, %d\n", p, address); return 0; }
為什么C++需要四種類型轉(zhuǎn)換
C風(fēng)格的轉(zhuǎn)換格式很簡單,但是有不少缺點(diǎn)的:
1.隱式類型轉(zhuǎn)化有些情況下可能會(huì)出問題:比如數(shù)據(jù)精度丟失
2.顯式類型轉(zhuǎn)換將所有情況混合在一起,代碼不夠清晰
因此C++提出了自己的類型轉(zhuǎn)化風(fēng)格,注意因?yàn)镃++要兼容C語言,所以C++中還可以使用C語言的轉(zhuǎn)化風(fēng)格。
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
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; int* p = &a; // 不支持的 //int address = static_cast<int>(p); // 意義不相近 return 0; }
reinterpret_cast
reinterpret_cast操作符通常為操作數(shù)的位模式提供較低層次的重新解釋,用于將一種類型轉(zhuǎn)換為另一種不同的類型
int main() { double d = 12.34; int a = static_cast<int>(d); // 意義相近 cout << a << endl; int* p = &a; // 不支持的 //int address = static_cast<int>(p); int address = reinterpret_cast<int>(p); // 意義不相近 return 0; }
const_cast
const_cast最常用的用途就是刪除變量的const屬性,方便賦值
int main() { // const int a = 2; volatile const int a = 2; int* p = const_cast<int*>(&a); //int* p = (int*)&a; *p = 3; cout << a << endl; // 2 cout << *p << endl; // 3 return 0; }
dynamic_cast
class A { public: virtual void f(){} public: int _a = 0; }; class B : public A { public: int _b = 1; }; // A*指針pa有可能指向父類,有可能指向子類 void fun(A* pa) { // 如果pa是指向子類,那么可以轉(zhuǎn)換,轉(zhuǎn)換表達(dá)式返回正確的地址 // 如果pa是指向父類,那么不能轉(zhuǎn)換,轉(zhuǎn)換表達(dá)式返回nullptr B* pb = dynamic_cast<B*>(pa); // 安全的 //B* pb = (B*)pa; // 不安全 if (pb) { cout << "轉(zhuǎn)換成功" << endl; pb->_a++; pb->_b++; cout << pb->_a << ":" << pb->_b << endl; } else { cout << "轉(zhuǎn)換失敗" << endl; pa->_a++; cout << pa->_a << endl; } } // A 是父類 B是子類 int main() { // 父類對(duì)象無論如何都是不允許轉(zhuǎn)換成子類對(duì)象的 // A aa; // B bb = dynamic_cast<B>(aa); // 不支持 // B bb = (B)aa; // 不支持 A aa; B bb; A* pa = &bb; B* pb = dynamic_cast<B*>(pa); //fun(nullptr); return 0; }
class A1 { public: virtual void f(){} public: int _a1 = 0; }; class A2 { public: virtual void f(){} public: int _a2 = 0; }; class B : public A1, public A2 { public: int _b = 1; }; int main() { B bb; A1* ptr1 = &bb; A2* ptr2 = &bb; cout << ptr1 << endl; cout << ptr2 << endl << endl; B* pb1 = (B*)ptr1; B* pb2 = (B*)ptr2; cout << pb1 << endl; cout << pb2 << endl << endl; B* pb3 = dynamic_cast<B*>(ptr1); B* pb4 = dynamic_cast<B*>(ptr2); cout << pb3 << endl; cout << pb4 << endl << endl; return 0; }
到此這篇關(guān)于一文帶你深入了解C++中的類型轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)C++類型轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++聚合關(guān)系類的構(gòu)造函數(shù)的調(diào)用順序詳解
下面小編就為大家?guī)硪黄狢++聚合關(guān)系類的構(gòu)造函數(shù)的調(diào)用順序詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考,一起跟隨小編過來看看吧2016-05-05C++ DFS算法實(shí)現(xiàn)走迷宮自動(dòng)尋路
這篇文章主要為大家詳細(xì)介紹了C++ DFS算法實(shí)現(xiàn)走迷宮自動(dòng)尋路,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05c++11 chrono全面解析(最高可達(dá)納秒級(jí)別的精度)
chrono是c++ 11中的時(shí)間庫,本文就來詳細(xì)的介紹一下chrono庫的具體使用,關(guān)鍵是理解里面時(shí)間段(Durations)、時(shí)間點(diǎn)(Time points)的概念,感興趣的可以了解一下2021-11-11c++文件監(jiān)控之FileSystemWatcher
為了監(jiān)控web程序的靜態(tài)文件是否被惡意改動(dòng),所以學(xué)習(xí)了一下FileSystemWatcher 類對(duì)文件的監(jiān)控,由于還在初級(jí)階段,這里只貼一下關(guān)于FileSystemWatcher學(xué)習(xí)的一些代碼2019-04-04C++實(shí)現(xiàn)LeetCode(676.實(shí)現(xiàn)神奇字典)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(676.實(shí)現(xiàn)神奇字典),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08Qt 使用Poppler實(shí)現(xiàn)pdf閱讀器的示例代碼
下面小編就為大家分享一篇Qt 使用Poppler實(shí)現(xiàn)pdf閱讀器的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01