C++中的四種強制類型轉換_基本用法及使用情境

來源:互聯網
上載者:User

C中的類型轉換:

  事情要從頭說起,這個頭就是C語言.我們已經習慣了使用C-like類型轉換,因為它強大而且簡單.

主要有一下兩種形式:

  • (new-type) expression

  • new-type (expression)

C風格的轉換格式很簡單,但是有不少缺點:

  1.轉換太過隨意,可以在任意類型之間轉換。你可以把一個指向const對象的指標轉換成指向非const對象的指標,把一個指向基類對象的指標轉換成一個衍生類別對象的指標,這些轉換之間的差距是非常巨大的,但是傳統的C語言風格的類型轉換沒有區分這些。

  2.C風格的轉換沒有統一的關鍵字和標示符。對於大型系統,做代碼排查時容易遺漏和忽略。

C++中的類型轉換:

C++風格完美的解決了上面兩個問題。1.對類型轉換做了細分,提供了四種不同類型轉換,以支援不同需求的轉換;2.類型轉換有了統一的標示符,利於代碼排查和檢視。下面分別來介紹這四種轉換:static_cast、dynamic_cast、const_cast和reinterpreter_cast.

  • static_cast,命名上理解是靜態類型轉換。如int轉換成char。

  • dynamic_cast,命名上理解是動態類型轉換。如子類和父類之間的多態類型轉換。

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

  • reinterpreter_cast,僅僅重新解釋類型,但沒有進行二進位的轉換。

一、static_cast轉換

  1.基本用法:static_cast expression

  2.使用情境

  a、用於類階層中基類和衍生類別之間指標或引用的轉換

  上行轉換(衍生類別—->基類)是安全的;

  下行轉換(基類—->衍生類別)由於沒有動態類型檢查,所以是不安全的。

  b、用於基礎資料型別 (Elementary Data Type)之間的轉換,如把int轉換為char,這種帶來安全性問題由程式員來保證

  c、把null 指標轉換成目標類型的null 指標

  d、把任何類型的運算式轉為void類型

  3.使用特點

  a、主要執行非多態的轉換操作,用於代替C中通常的轉換操作

  b、隱式轉換都建議使用static_cast進行標明和替換

int n = 6;double d = static_cast<double>(n); // 基本類型轉換int *pn = &n;double *d = static_cast<double *>(&n) //無關類型指標轉換,編譯錯誤void *p = static_cast<void *>(pn); //任意類型轉換成void類型

二、dynamic_cast轉換

  1.基本用法:dynamic_cast expression

  2.使用情境:只有在衍生類別之間轉換時才使用dynamic_cast,type-id必須是類指標,類引用或者void*。

  3.使用特點

  a、基類必須要有虛函數,因為dynamic_cast是運行時類型檢查,需要運行時類型資訊,而這個資訊是儲存在類的虛函數表中,只有一個類定義了虛函數,才會有虛函數表(如果一個類沒有虛函數,那麼一般意義上,這個類的設計者也不想它成為一個基類)。

  b、對於下行轉換,dynamic_cast是安全的(當類型不一致時,轉換過來的是null 指標),而static_cast是不安全的(當類型不一致時,轉換過來的是錯誤意義的指標,可能造成踩記憶體,非法訪問等各種問題)

  c、dynamic_cast還可以進行交叉轉換

class BaseClass {public:  int m_iNum;  virtual void foo(){};//基類必須有虛函數。保持多台特性才能使用dynamic_cast};class DerivedClass: public BaseClass {public:  char *m_szName[100];  void bar(){};};  BaseClass* pb = new DerivedClass();DerivedClass *pd1 = static_cast<DerivedClass *>(pb);//子類->父類,靜態類型轉換,正確但不推薦DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb);//子類->父類,動態類型轉換,正確BaseClass* pb2 = new BaseClass();//父類->子類,靜態類型轉換,危險!訪問子類m_szName成員越界DerivedClass *pd21 = static_cast<DerivedClass *>(pb2);//父類->子類,動態類型轉換,安全的。結果是NULLDerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2);

三、const_cast轉換

  1.基本用法:const_castexpression

  2.使用情境

  a、常量指標轉換為非常量指標,並且仍然指向原來的對象

  b、常量引用被轉換為非常量引用,並且仍然指向原來的對象

  3.使用特點

  a、cosnt_cast是四種類型轉換符中唯一可以對常量進行操作的轉換符

  b、去除常量性是一個危險的動作,盡量避免使用。一個特定的情境是:類通過const提供重載時,一般都是非常量函數調用const_cast將參數轉換為常量,然後調用常量函數,然後得到結果再調用const_cast 去除常量性。

struct SA {  int i;};const SA ra;//ra.i = 10; //直接修改const類型,編譯錯誤SA &rb = const_cast<SA&>(ra);rb.i = 10;

四、reinterpret_cast轉換

  1.基本用法:reinterpret_castexpression

  2.使用情境:不到萬不得已,不用使用這個轉換符,高危操作

  3.使用特點:  

  a、reinterpret_cast是從底層對資料進行重新解釋,依賴具體的平台,可移植性差

  b、reinterpret_cast可以將整型轉換為指標,也可以把指標轉換為數組

  c、reinterpret_cast可以在指標和引用裡進行肆無忌憚的轉換

int doSomething(){return 0;};//FuncPtr is 一個指向函數的指標,該函數沒有參數,傳回值類型為 voidtypedef void(*FuncPtr)();//10個FuncPtrs指標的數組 讓我們假設你希望(因為某些莫名其妙的原因)把一個指向下面函數的指標存//入funcPtrArray數組:FuncPtr funcPtrArray[10];funcPtrArray[0] = &doSomething;// 編譯錯誤!類型不符,reinterpret_cast可以讓編譯器以你的方法去看待它們:funcPtrArrayfuncPtrArray[0] = reinterpret_cast<FuncPtr>(&doSomething);//不同函數指標類型之間進行轉換

總結:

去const屬性用const_cast。

基本類型轉換用static_cast。

多態類之間的類型轉換用daynamic_cast。

不同類型的指標類型轉換用reinterpreter_cast。

相關文章:

C++ 的強制類型轉換

【c#教程】C# 類型轉換

相關視頻:

PHP資料類型轉換之自動類型轉換

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.