1. 程式人生 > >[c++基礎] 四種類型轉換和隱式型別轉換

[c++基礎] 四種類型轉換和隱式型別轉換

static_cast<type-id >( expression )  

用於數值型別之間的轉換,也可以用於指標之間的轉換,編譯時已經確定好,效率高,但須要自己保證其安全性。

(1)用於數值之間的轉化, 可以在相關指標在void* 之間轉換

   

(2)在基類和派生類之間進行轉換(必須是有繼承關係的兩個類之間)

上行轉換:子類指標或引用轉換成基類表示——安全

下行轉換:基類指標或引用轉換成子類表示——危險(沒有動態型別檢查

   

dynamic_cast < type-id> ( expression)

只用於物件的指標和引用之間的轉換,需要虛擬函式

尤其是向下型別轉換,是安全的。與static_cast不同,在下行轉換,dynamic_cast會檢查轉換是否會返回一個被請求的有效的完整物件,否則返回值為NULL. 

檢測在執行時進行,是基於RTTI資料資訊的,執行時檢測,安全,但是效率低。

  

dynamic_cast 如何保證轉換是安全的?

引入RTTI,其儲存著類執行的相關資訊,記錄的類的名字和類的繼承關係鏈。使得物件可以知道自己的名字以及在繼承鏈中的位置。因為RTTI依賴於虛表,所以用dynamic_cast對應的類一定要有虛擬函式。

const_cast< type-id> ( expression)

這個轉換型別操縱傳遞物件的const屬性,或者是設定或者是移除:
程式碼:
class C {};
const C *a = new C;
C *b = const_cast<C *>(a);

reinterpret_cast< type-id> ( expression)

用在任意指標(或引用)型別之間的轉換;以及指標與足夠大的整數型別之間的轉換;從整數型別(包括列舉型別)到指標型別,無視大小。


隱式型別轉換

1)兩種常用的實現隱式類型別轉換的方式:

a、使用單引數的建構函式或N個引數中有N-1個是預設引數的建構函式

b、使用operator目標型別() const

例如:
class Rational {

public:
  ...
  operator double()const;                  // 轉換Rational類成double

型別
};

在下面這種情況下,這個函式會被自動呼叫:
Rational r(1,2);                           // r
的值是1/2 
double d = 0.5 *r;                         //
轉換 r double,然後做乘法

(2) 避免隱式型別轉換:單引數的建構函式或N個引數中有N-1個是預設引數的建構函式宣告之前加上explicit