日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
C++的轉(zhuǎn)換手段并與Explicit關(guān)鍵詞配合使用

 [[354653]]

晉安ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:18982081108(備注:SSL證書(shū)合作)期待與您的合作!

C中我們會(huì)進(jìn)行各種類(lèi)型的強(qiáng)制轉(zhuǎn)化,而在C中我們經(jīng)??梢钥吹竭@種轉(zhuǎn)換

 
 
 
 
  1. memset(OTA_FLAG_ADDRESS,(uint8_t*)&OTA_Flag,sizeof(OTA_Flag)); 

而C++的類(lèi)型轉(zhuǎn)化和C差別很多,那么C++里面的類(lèi)型轉(zhuǎn)化是怎么用的呢。C++除了隱式轉(zhuǎn)換和顯示轉(zhuǎn)化,顯示轉(zhuǎn)化是我們熟知,有四個(gè)顯示轉(zhuǎn)化函數(shù):static_cast、dynamic_cast、const_cast、reinterpret_cast,主要運(yùn)用于繼承關(guān)系類(lèi)間的強(qiáng)制轉(zhuǎn)化。

下面我就給大家說(shuō)道說(shuō)道。

隱式轉(zhuǎn)化

c++語(yǔ)言不會(huì)直接將兩個(gè)不同類(lèi)型的值相加,二十先根據(jù)類(lèi)型轉(zhuǎn)化規(guī)則設(shè)法將運(yùn)算對(duì)象的類(lèi)型統(tǒng)一后再求值。例如 int value = 3.14 +3;這個(gè)程序是可以編譯通過(guò)的,只不過(guò)編譯器可能會(huì)警告改運(yùn)算損失了精度。這樣的類(lèi)型轉(zhuǎn)化是自動(dòng)運(yùn)行,無(wú)需程序員介入,因此,它們被稱(chēng)為隱式轉(zhuǎn)換

何時(shí)會(huì)發(fā)生隱式轉(zhuǎn)化:

在下面的情況中,編譯器會(huì)自動(dòng)的轉(zhuǎn)化運(yùn)算對(duì)象的類(lèi)型:

  1. 在大多數(shù)表達(dá)式中,需要將比int類(lèi)型小的整型值首先提升到較大的整數(shù)類(lèi)型會(huì)進(jìn)行隱式轉(zhuǎn)化
  2. 在條件中,非布爾值轉(zhuǎn)換成布爾類(lèi)型
  3. 初始化過(guò)程中,初始值轉(zhuǎn)化成變量的類(lèi)型;在賦值語(yǔ)句中,右側(cè)運(yùn)算對(duì)象轉(zhuǎn)化成左側(cè)運(yùn)算對(duì)象的類(lèi)型
  4. 函數(shù)調(diào)用時(shí)候也會(huì)發(fā)生類(lèi)型轉(zhuǎn)化(實(shí)參類(lèi)型轉(zhuǎn)化)

顯示轉(zhuǎn)化

C風(fēng)格的強(qiáng)制轉(zhuǎn)換(Type Cast)容易理解,不管什么類(lèi)型的轉(zhuǎn)換都可以使用使用下面的方式

 
 
 
 
  1. Type b = (Type)a; 

當(dāng)然,C++也是支持C風(fēng)格的強(qiáng)制轉(zhuǎn)換,但是C風(fēng)格的強(qiáng)制轉(zhuǎn)換可能帶來(lái)一些隱患,讓一些問(wèn)題難以察覺(jué).所以C++提供了一組可以用在不同場(chǎng)合的強(qiáng)制轉(zhuǎn)換的函數(shù).

C++提供了四種強(qiáng)制類(lèi)型轉(zhuǎn)化的函數(shù),分別是:

static_cast,命名上理解是靜態(tài)類(lèi)型轉(zhuǎn)換。大部分C實(shí)現(xiàn)的轉(zhuǎn)化,用這個(gè)函數(shù)就可以了。

const_cast,字面上理解就是去const屬性。

dynamic_cast,命名上理解是動(dòng)態(tài)類(lèi)型轉(zhuǎn)換。如子類(lèi)和父類(lèi)之間的多態(tài)類(lèi)型轉(zhuǎn)換。

reinterpret_cast,僅僅重新解釋類(lèi)型,但沒(méi)有進(jìn)行二進(jìn)制的轉(zhuǎn)換。

static_cast:

任何具有明確定義的類(lèi)型轉(zhuǎn)化,只要不包含底層const,都可以使用static_cast,舉一個(gè)例子。

 
 
 
 
  1. double slop = static_cast(j) / i;//進(jìn)行強(qiáng)制轉(zhuǎn)化成double 
  2. int*pn =&n; 
  3. double*dp = static_cast(&pn) //無(wú)關(guān)類(lèi)型指針轉(zhuǎn)換,編譯錯(cuò)誤 
  4.  void*p = &n; 
  5.  double*d = static_cast(&p) //將void*轉(zhuǎn)化為初始的指針類(lèi)型 

static_cast強(qiáng)制轉(zhuǎn)換只會(huì)在編譯時(shí)檢查,但沒(méi)有運(yùn)行時(shí)類(lèi)型檢查來(lái)保證轉(zhuǎn)換的安全性。同時(shí),static_cast也不能去掉expression的const、volitale、或者_(dá)_unaligned屬性。

const_cast:

const_cast<>可以實(shí)現(xiàn)將const 指針類(lèi)型轉(zhuǎn)普通指針,const_cast操作不能在不同的種類(lèi)間轉(zhuǎn)換。相反,它僅僅把一個(gè)它作用的表達(dá)式轉(zhuǎn)換成常量。它可以使一個(gè)本來(lái)不是const類(lèi)型的數(shù)據(jù)轉(zhuǎn)換成const類(lèi)型的,或者把const屬性去掉。如果一個(gè)對(duì)象本身不是一個(gè)常量,使用強(qiáng)制類(lèi)型轉(zhuǎn)化獲得寫(xiě)權(quán)限是合法的行為。然而如果對(duì)象是一個(gè)常量,再使用const_cast執(zhí)行寫(xiě)操作就會(huì)產(chǎn)生未定義的后果。

只有const_cast能改變表達(dá)式的常量屬性,使用其他形式的命名強(qiáng)制類(lèi)型轉(zhuǎn)化改變表達(dá)式的常量屬性都將引發(fā)編譯器錯(cuò)誤。同樣的,也不能用const_cast改變表達(dá)式的類(lèi)型:

 
 
 
 
  1. const char *cp; 
  2.  
  3. char *q = static_cast(cp);//錯(cuò)誤:static_cast不能轉(zhuǎn)換掉const性質(zhì) 
  4. static_cast(cp);//正確:字符串字面值轉(zhuǎn)換成string類(lèi)型 
  5. const_cast(cp);//錯(cuò)誤:const_cast 只改變常量屬性 
  6. const_cast(cp);//正確 
  7. const int p = 0; 
  8. int &rb = const_cast(p);//正確 
  9. rb =10; 

dynamic_cast:

1.其他三種都是編譯時(shí)完成的,dynamic_cast是運(yùn)行時(shí)處理的,運(yùn)行時(shí)要進(jìn)行類(lèi)型檢查。

2.不能用于內(nèi)置的基本數(shù)據(jù)類(lèi)型的強(qiáng)制轉(zhuǎn)換。

3.dynamic_cast轉(zhuǎn)換如果成功的話(huà)返回的是指向類(lèi)的指針或引用,轉(zhuǎn)換失敗的話(huà)則會(huì)返回NULL。

4.使用dynamic_cast進(jìn)行轉(zhuǎn)換的,基類(lèi)中一定要有虛函數(shù),否則編譯不通過(guò)。可以從父類(lèi)轉(zhuǎn)基類(lèi),但是可能為空

5.在類(lèi)的轉(zhuǎn)換時(shí),在類(lèi)層次間進(jìn)行上行轉(zhuǎn)換時(shí),dynamic_cast和static_cast的效果是一樣的。在進(jìn)行下行轉(zhuǎn)換時(shí),dynamic_cast具有類(lèi)型檢查的功能,比static_cast更安全。向上轉(zhuǎn)換即為指向子類(lèi)對(duì)象的向下轉(zhuǎn)換,即將父類(lèi)指針轉(zhuǎn)化子類(lèi)指針。向下轉(zhuǎn)換的成功與否還與將要轉(zhuǎn)換的類(lèi)型有關(guān),即要轉(zhuǎn)換的指針指向的對(duì)象的實(shí)際類(lèi)型與轉(zhuǎn)換以后的對(duì)象類(lèi)型一定要相同,否則轉(zhuǎn)換失敗。

 
 
 
 
  1. class BaseClass {  
  2. public:  
  3.    int Num;  
  4.    virtualvoid foo(){}; //基類(lèi)必須有虛函數(shù)。保持多臺(tái)特性才能使用dynamic_cast  
  5.  };  
  6. DerivedClass: public BaseClass {  
  7. public:  
  8.   char*m_szName[100]; 
  9.   void bar(){}; 
  10. }; 
  11. int main(int argc,char** argv) 
  12.   BaseClass* pb =new DerivedClass(); 
  13.   DerivedClass *pd1 = static_cast(pb); //子類(lèi)->父類(lèi),靜態(tài)類(lèi)型轉(zhuǎn)換,正確但不推薦 
  14.   DerivedClass *pd2 = dynamic_cast(pb); //子類(lèi)->父類(lèi),動(dòng)態(tài)類(lèi)型轉(zhuǎn)換,正確 
  15.   BaseClass* pb2 =new BaseClass(); 
  16.   DerivedClass *pd21 = static_cast(pb2); //父類(lèi)->子類(lèi),靜態(tài)類(lèi)型轉(zhuǎn)換,危險(xiǎn)!訪問(wèn)子類(lèi)m_szName成員越界 
  17.   DerivedClass *pd22 = dynamic_cast(pb2); //父類(lèi)->子類(lèi),動(dòng)態(tài)類(lèi)型轉(zhuǎn)換,安全的。結(jié)果是NULL 

reinterpret_cast:

實(shí)現(xiàn)指針轉(zhuǎn)整形,整形轉(zhuǎn)指針.reinterpret_cast是強(qiáng)制類(lèi)型轉(zhuǎn)換符用來(lái)處理無(wú)關(guān)類(lèi)型轉(zhuǎn)換的,通常為操作數(shù)的位模式提供較低層次的重新解釋!但是它僅僅是重新解釋了給出的對(duì)象的比特模型,并沒(méi)有進(jìn)行二進(jìn)制的轉(zhuǎn)換!

它是用在任意的指針之間的轉(zhuǎn)換,引用之間的轉(zhuǎn)換,指針和足夠大的int型之間的轉(zhuǎn)換,整數(shù)到指針的轉(zhuǎn)換。最普通的用途就是在函數(shù)指針類(lèi)型之間進(jìn)行轉(zhuǎn)換。

請(qǐng)看一個(gè)簡(jiǎn)單代碼

 
 
 
 
  1. int doSomething(){return 0;}; 
  2. typedef void(*FuncPtr)(); //FuncPtr is 一個(gè)指向函數(shù)的指針,該函數(shù)沒(méi)有參數(shù),返回值類(lèi)型為 void 
  3. FuncPtr funcPtrArray[10]; //10個(gè)FuncPtrs指針的數(shù)組 讓我們假設(shè)你希望(因?yàn)槟承┠涿畹脑颍┌岩粋€(gè)指向下面函數(shù)的指針存入funcPtrArray數(shù)組: 
  4. funcPtrArray[0] =&doSomething;// 編譯錯(cuò)誤!類(lèi)型不匹配,reinterpret_cast可以讓編譯器以你的方法去看待它們:funcPtrArray 
  5. funcPtrArray[0] = reinterpret_cast(&doSomething); //不同函數(shù)指針類(lèi)型之間進(jìn)行轉(zhuǎn)換 

explicit關(guān)鍵字(顯示的類(lèi)型轉(zhuǎn)化運(yùn)算符)

C++提供了關(guān)鍵字explicit,可以阻止不應(yīng)該允許的經(jīng)過(guò)轉(zhuǎn)換構(gòu)造函數(shù)進(jìn)行的隱式轉(zhuǎn)換的發(fā)生。即聲明為explicit的構(gòu)造函數(shù)不能在隱式轉(zhuǎn)換中使用。

explicit關(guān)鍵字只能用于類(lèi)內(nèi)部的構(gòu)造函數(shù)聲明上,而不能用在類(lèi)外部的函數(shù)定義上?,F(xiàn)在Things類(lèi)像這樣:

 
 
 
 
  1. class Things 
  2. public: 
  3.    Things(const std::string&name =""); 
  4.      explicit operator int() const{return val;}  
  5.     //編譯器不會(huì)自動(dòng)執(zhí)行這一類(lèi)型的 
  6. }; 

下面再看個(gè)好一點(diǎn)的例子進(jìn)行對(duì)比一下:

 
 
 
 
  1. // 類(lèi)的通過(guò)構(gòu)造函數(shù)的隱式轉(zhuǎn)換: 
  2. #include  
  3. using namespace std; 
  4.  
  5. class A {}; 
  6.  
  7. class B { 
  8. public: 
  9.   // conversion from A (constructor): 
  10.   B (const A& x) {} 
  11.   // conversion from A (assignment): 
  12.   B& operator= (const A& x) {return *this;} 
  13.   // conversion to A (type-cast operator) 
  14.   operator A() {return A();} 
  15. }; 
  16.  
  17. int main () 
  18.   A foo; 
  19.   B bar = foo;    // 調(diào)用構(gòu)造函數(shù)實(shí)現(xiàn)隱式類(lèi)型轉(zhuǎn)換 
  20.   bar = foo;      // calls assignment 
  21.   foo = bar;      // calls type-cast operator,相當(dāng)于 foo = A(bar); 
  22.   return 0; 

再看使用explicit的一個(gè)例子:

 
 
 
 
  1. #include  
  2. using namespace std; 
  3.  
  4. class A {}; 
  5.  
  6. class B { 
  7. public: 
  8.   explicit B (const A& x) {} 
  9.   B& operator= (const A& x) {return *this;} 
  10.   operator A() {return A();} 
  11. }; 
  12.  
  13. void fn (B x) {}  // 當(dāng)我們希望x只能是B類(lèi)型時(shí),我們就需要禁止隱式類(lèi)型轉(zhuǎn)換 
  14.  
  15. int main () 
  16.   A foo; 
  17.   B bar (foo);  // 必須顯式類(lèi)型轉(zhuǎn)換,不再允許B bar = foo;  
  18.   bar = foo; 
  19.   foo = bar; 
  20.  
  21. //  fn (foo);  // 不允許隱式類(lèi)型轉(zhuǎn)換 
  22.   fn (bar);   
  23.  
  24.   return 0; 

這就是我分享的c++的轉(zhuǎn)化類(lèi)型方法,其中參考了好多人的文字,此外如果大家有什么更好的思路,也歡迎分享交流哈。

本文轉(zhuǎn)載自微信公眾號(hào)「羽林君」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系羽林君公眾號(hào)。 

 


本文題目:C++的轉(zhuǎn)換手段并與Explicit關(guān)鍵詞配合使用
標(biāo)題鏈接:http://www.dlmjj.cn/article/cdgepop.html