C++ 類型轉換

這篇文章主要對C++的類型轉換作一個總結。

這裏順便提一下C語言的類型轉換:

C語言的類型轉換比較簡單粗暴,分爲隱式類型轉換和顯示類型轉換。

隱式類型轉換規則:

  • 算數運算式中,低類型轉化爲高類型;
  • 賦值表達式中,表達式的值轉換爲左邊變量的類型;
  • 函數調用時,實參轉換爲形參的類型;
  • 函數返回值,return表達式轉換爲返回值類型;

                                           

                                                          圖1 低類型轉換爲高類型

顯示類型轉換格式:(type-id)expression

    C風格的類型轉換有不少缺點,有的時候C風格的轉換時不合適的,因爲它可以在任意類型之間轉換,比如可以把一個指向const對象的指針轉換成指向非const對象的指針,把一個指向基類對象的指針轉換成指向一個派生類對象的指針,這兩種轉換之間的差別是巨大的,但是傳統的C語言風格的類型轉換沒有區分這些。還有一個缺點就是,C風格的轉換不容易查找,他由一個括號加上標識符組成,而這樣的東西在C++程序裏一大堆。所以C++爲了克服這些缺點,引進了4中新的類型轉換操作符。

1.靜態類型轉換—static_cast

1.1 格式:static_cast<type-id>(expression)

    static_cast主要用於基本類型之間、基本類型指針和空指針間的轉換(不能用於基本類型指針之間的轉換),該運算符把expression轉換爲type-id類型,但是沒有運行時類型檢查來保證轉換的安全性。

1.2 規則:

  • 用於類層次結構中基類和子類之間指針或引用的轉換,可以進行上行轉換(把子類的指針或引用轉換成基類表示)是安全的和下行轉換(把基類指針或引用轉換成子類表示)式,由於沒有動態類型檢查,所以是不安全的;
  • 用於基本數據類型之間的轉化(編譯器隱式執行的類型轉換都可以用它來轉換),例如:int與char,int 與float等。這種轉換的安全性也需要開發人員來保證;
  • 把空指針轉換成目標類型的空指針;
  • 把任何類型的表達式轉換成void類型;
  • static_cast不能轉換掉expression的const、volitale、或者_unaligned屬性;

2. 動態類型轉換—dynamic_cast

2.1 格式:dynamic_cast<type-id>(expression)

    dynamic_cast主要用於類層次結構中父類和子類之間指針和引用的轉換,由於具有運行時類型檢查,因此可以保證下行轉換的安全性,安全性是指:轉換成功就返回轉換後的正確類型指針,如果轉換失敗,則返回NULL,之所以說static_cast在下行轉換時不安全,是因爲即使轉換失敗,它也不返回NULL。

2.2 規則

  • dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換;
  • 在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;
  • 在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全;
  • 如果type-id是類指針類型,那麼expression也必須是一個指針,如果type-id是一個引用,那麼expression也必須是一個引用;

3. 重解釋類型轉換—reinterpret_cast

3.1 格式:reinterpret_cast<type-id>(expression)

3.2 規則:reinterpret_cast用在任意指針(或引用)類型之間的轉換,以及指針與足夠大的整數類型之間的轉換;從整數類型(包括枚舉類型)到指針類型,無視大小。type-id必須是一個指針、引用、算數類型、函數指針或成員指針。它可以把一個指針轉換成一個整數,也可以把一個整數轉換成一個指針。

4. 常類型轉換—const_cast

4.1 格式:const_cast<type-id>(expression)

    用於修改類型的const或volatile屬性。除了const或volatile修飾之外,type-id和expression的類型是一樣的。使用const_cast 去除const 限定,通常是爲了函數能夠接受這個實際參數。

4.2 規則

  • 常量指針被轉換爲非常量的指針,並仍然指向原來的對象;
  • 常量引用被轉換爲非常量的引用,並仍然指向原來的對象;
  • const_cast一般用於修改底指針。如const char *p形式;
#include <iostream>
using namespace std;

int main(){
    const int g = 20;
    int &h = const_cast<int &>(g);
    cout<<"h = "<<h<<" &h = "<<&h<<endl;
    h = 10;
    cout<<"h = "<<h<<" &h = "<<&h<<endl;
    cout<<"g = "<<g<<" &g = "<<&g<<endl;
}

輸出結果:

    雖然能夠改變h的值,指針也指向原來的對象,但是兩個變量的值不一樣。說明C++裏const定義的值是不會改變的。IBM的C++指南稱“h = 10”爲“未定義行爲”。所謂未定義,是說這個語句在標準C++中沒有明確的規定。

Reference :

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章