C++中的static_cast, dynamic_cast和reinterpret_cast

來源:互聯網
上載者:User

鄭重聲明:本文是筆者根據個人理解所寫,錯誤難免,歡迎拍磚!

       可以任意轉載、修改,轉載時是否標明出處,隨君而定!

static_cast

用於“良性”和“適度良性”轉換,包括不用強制轉換(如自動類型轉換)。static_cast全部用於明確定義的轉換,包括編譯器允許我們所做的不用強制轉換的“安全”轉換和不太安全但清楚定義的轉換。

用法:static_cast < type-id > ( expression
該運算子把expression轉換為type-id類型,但沒有在運行時進行類型檢查來保證轉換的安全性。static_cast包含的類型轉換包括一下幾種:

A、典型的非強制變換

B、窄化(有資訊丟失)變換

C、使用void*的強制變換

D、隱式類型變換

E、類層次的靜態定位

  a. 向上轉換是安全的,即將子類的指標或引用轉換為基類
  b. 向下轉換是不安全的,即將基類指標或引用轉換成子類,因為是靜態轉換,沒有在運行時進行類型檢查,應使用dynamic_cast。

 1 int i = 0x7fff;  // max pos value = 32767 2 long l = 0; 3 float f = 1.0f; 4  5 // A: typeical castless conversions: 6 l = static_cast<long>(i); 7  8 // B: narrowing conversions: 9 i = static_cast<int>(f);10 11 // C: forcing a conversion from void* :12 void* pvoid = &i;13 float* pf = static_cast<float*>(pvoid);14 15 // D: Implicit type conversions, normally performed by the compiler16 double d = 0.0;17 int x = d; // Automatic type conversion18 x = static_cast<int>(d);  // More explicit

 注意:static_cast不能轉換掉expression的const、volitale、或者__unaligned屬性。

dynamic_cast

用法:dynamic_cast < type-id > ( expression )
該運算子把expression轉換成type-id類型的對象。type-id必須是類的指標、類的引用或者void *;
如果type-id是類指標類型,那麼expression也必須是一個指標,如果type-id是一個引用,那麼expression也必須是一個引用。

當使用dynamic_cast來試著向下類型轉換一個特定的類型,僅當類型轉換是爭取的並且是成功的時,傳回值是一個指向所需類型的指標,否則它將返回0來表示轉換失敗。

dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。
在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;

在進行下行轉換時,dynamic_cast具有類型檢查的功能,比static_cast更安全。

 1 #include <iostream> 2 using namespace std; 3  4 class CPet { public : virtual ~CPet() {} }; 5 class CDog : public CPet {}; 6 class CCat : public CPet {}; 7  8 int main() 9 {10     CPet* pPet = new CCat; // Upcast, safe11     // Try to cast it to CCat* :12     CCat* pCat = dynamic_cast<CCat*>(pPet); // cast success13     // Try to cast it to CDog* :14     CDog* pDog = dynamic_cast<CDog*>(pPet); // cast fail15 16     cout << "pDog = " << (long)pDog << endl;17     cout << "pCat = " << (long)pCat << endl;18 }

 在上面的程式碼片段中,將pPet向下轉換為CCat*類型成功了(因為CPet* pPet = new CCat;),轉換為CDog*類型失敗了,說明dynamic_cast會進行類型檢測。

當使用dynamic_cast時,必須對一個真正多態的層次進行操作(即它含有虛函數),這是因為dynamic_cast使用了儲存在VTABLE中的資訊來判斷實際的類型。

注意:無論何時進行向下類型轉換,我們都應該進行類型檢查以確保轉換是成功的(即傳回值非0)。但我們不用確保指標要完全一樣,因為通常在向上和向下類型轉換時指標會進行調整(特別是多重繼承的情況下)。

dynamic _cast運行時需要一點額外的開銷,不多,但是執行大量的dynamic_cast時就說明我們的設計有問題了,也會導致效能損失。在進行向下轉換時,如果我們已經明確知道是什麼類型,就可以使用static_cast,以避免調用dynamic_cast產生的額外開銷。比如上面的將pPet向下轉換為CCat*類型,可以這樣寫:

CCat* pCat = static_cast<CCat*>(pPet);
reinterpret_cast

這是最不安全的一種轉換機制,最有可能出問題。reinterpret_cast把對象假象為模式(為了某種隱秘的目的),彷彿它是一個完全不同的類型對象。這是低級的位元模式,C因此而名稱不佳。在使用reinterpret_cast做任何事之前,實際上總是需要reinterpret_cast回到原來的類型(或者把變數看做是它原來的類型)。說白了,就是將原來的類型隱藏起來,用的時候再轉換回去,否則編譯失敗。

用法:reinterpret_cast< type-id > (expression)
type-id必須是一個指標、引用、算術類型、函數指標或者成員指標。
它可以把一個指標轉換成一個整數,也可以把一個整數轉換成一個指標(先把一個指標轉換成一個整數,
在把該整數轉換成原類型的指標,還可以得到原先的指標值)。

const_cast

const_cast用來修改類型的const或volatile屬性,即可以將const轉換為非const以及volatile轉換為非volatile,這是const_cast唯一允許的轉換。除了const 或volatile修飾之外, type_id和exdivssion的類型是一樣的。
用法:const_cast< type-id > (expression)
常量指標被轉化成非常量指標,並且仍然指向原來的對象;
常量引用被轉換成非常量引用,並且仍然指向原來的對象;常量對象被轉換成非常量對象。

Voiatile和const類試。舉如下一例:

 1 class B 2 { 3 public: 4     int m_iNum; 5 } 6 void foo() 7 { 8     const B b1; 9     b1.m_iNum = 100; //comile error10     B b2 = const_cast<B>((b1);11     b2. m_iNum = 200; //fine12 }

 上面的代碼編譯時間會報錯,因為b1是一個常量對象,不能對它進行改變;

使用const_cast把它轉換成一個常量對象,就可以對它的資料成員任意改變。注意:b1和b2是兩個不同的對象。

簡單總結一下:

dynamic_cast:   通常在基類和衍生類別之間轉換時使用;
const_cast:   主要針對const和volatile的轉換.   
static_cast:   一般的轉換,如果你不知道該用哪個,就用這個。   
reinterpret_cast:   用於進行沒有任何關聯之間的轉換,比如一個字元指標轉換為一個整形數。

 

參考資料:

http://blog.csdn.net/Lambol_8309/article/details/4534338

http://blog.sina.com.cn/s/blog_4a84e45b0100f57m.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.