C++的強制類型轉換

c/c++強制類型轉換

Q:什麼是C風格轉換?什麼是static_cast, dynamic_cast 以及 reinterpret_cast?區別是什麼?爲何要注意?
A:轉換的含義是經過改變一個變量的類型爲別的類型從而改變該變量的表示方式。爲了類型轉換一個簡單對象爲另外一個對象你會使用傳統的類型轉換操做符。好比,爲了轉換一個類型爲doubole的浮點數的指針到整型:
代碼:
int i;
double d;
i = (int) d;或者:i = int (d);
c++

對於具備標準定義轉換的簡單類型而言工做的很好。然而,這樣的轉換符也能不分皁白的應用於類(class)和類的指針。ANSI-C++標準定義了四個新的轉換符:'reinterpret_cast', 'static_cast', 'dynamic_cast' 和 'const_cast',目的在於控制類(class)之間的類型轉換。
代碼:
express

  • reinterpret_cast<new_type>(expression)
  • dynamic_cast<new_type>(expression)
  • static_cast<new_type>(expression)
  • const_cast<new_type>(expression)

 

1 reinterpret_cast

reinterpret_cast 轉換一個指針爲其它類型的指針。它也容許從一個指針轉換爲整數類型。反之亦然。(譯註:是指針具體的地址值做爲整數值?)
這個操做符可以在非相關的類型之間轉換。操做結果只是簡單的從一個指針到別的指針的值的二進制拷貝。在類型之間指向的內容不作任何類型的檢查和轉換。若是狀況是從一個指針到整型的拷貝,內容的解釋是系統相關的,因此任何的實現都不是方便的。一個轉換到足夠大的整型可以包含它的指針是可以轉換回有效的指針的。
代碼:
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B *>(a);
reinterpret_cast  就像傳統的類型轉換同樣對待全部指針的類型轉換。

2 static_cast

static_cast 容許執行任意的隱式轉換和相反轉換動做。(即便它是不容許隱式的)
意思是說它容許子類類型的指針轉換爲父類類型的指針(這是一個有效的隱式轉換),同時,也可以執行相反動做:轉換父類爲它的子類
在這最後例子裏,被轉換的父類沒有被檢查是否與目的類型相一致。
代碼:
class Base {};
class Derived : public Base {};

Base *a    = new Base;
Derived *b = static_cast<Derived *>(a);
static_cast  除了操做類型指針,也能用於執行類型定義的顯式的轉換,以及基礎類型之間的標準轉換:
代碼:
double d = 3.14159265;
int    i = static_cast<int>(d);

3 dynamic_cast
安全

dynamic_cast只用於對象的指針和引用。當用於多態類型時,它容許任意的隱式類型轉換以及相反過程。不過,與static_cast不一樣,在後一種狀況裏(注:即隱式轉換的相反過程),dynamic_cast會檢查操做是否有效。也就是說,它會檢查轉換是否會返回一個被請求的有效的完整對象。
檢測在運行時進行。若是被轉換的指針不是一個被請求的有效完整的對象指針,返回值爲NULL.
代碼:
class Base { virtual dummy() {} };
class Derived : public Base {};

Base* b1 = new Derived;
Base* b2 = new Base;

Derived* d1 = dynamic_cast<Derived *>(b1);          // succeeds
Derived* d2 = dynamic_cast<Derived *>(b2);          // fails: returns 'NULL'

若是一個引用類型執行了類型轉換而且這個轉換是不可能的,一個bad_cast的異常類型被拋出:
代碼:
class Base { virtual dummy() {} };
class Derived : public Base { };

Base* b1 = new Derived;
Base* b2 = new Base;

Derived d1 = dynamic_cast<Derived &*>(b1);          // succeeds
Derived d2 = dynamic_cast<Derived &*>(b2);          // fails: exception thrown

4 const_cast

這個轉換類型操縱傳遞對象的const屬性,或者是設置或者是移除:
代碼:
class C {};
const C *a = new C;

C *b = const_cast<C *>(a);
其它三種操做符是不能修改一個對象的常量性的。
注意:'const_cast'也能改變一個類型的volatile qualifier。

 spa

 C++的四種強制轉型形式每一種適用於特定的目的: 

  ·dynamic_cast 主要用於執行「安全的向下轉型(safe downcasting)」,也就是說,要肯定一個對象是不是一個繼承體系中的一個特定類型。它是惟一不能用舊風格語法執行的強制轉型,也是惟一可能有重大運行時代價的強制轉型。
    
    ·static_cast 能夠被用於強制隱型轉換(例如,non-const 對象轉型爲 const 對象,int 轉型爲 double,等等),它還能夠用於不少這樣的轉換的反向轉換(例如,void* 指針轉型爲有類型指針,基類指針轉型爲派生類指針),可是它不能將一個 const 對象轉型爲 non-const 對象(只有 const_cast 能作到),它最接近於C-style的轉換。
    
  ·const_cast 通常用於強制消除對象的常量性。它是惟一能作到這一點的 C++ 風格的強制轉型。 

  ·reinterpret_cast 是特地用於底層的強制轉型,致使實現依賴(implementation-dependent)(就是說,不可移植)的結果,例如,將一個指針轉型爲一個整數。這樣的強制轉型在底層代碼之外應該極爲罕見。
指針

相關文章
相關標籤/搜索