1. 程式人生 > >【C++】static_cast AND reinterpret_cast

【C++】static_cast AND reinterpret_cast

用法:static_cast < type-id > ( expression )

該運算子把expression轉換為type-id型別,但沒有執行時型別檢查來保證轉換的安全性。它主要有如下幾種用法:

①用於類層次結構中基類(父類)和派生類(子類)之間指標或引用的轉換。

進行上行轉換(把派生類的指標或引用轉換成基類表示)是安全的;

進行下行轉換(把基類指標或引用轉換成派生類表示)時,由於沒有動態型別檢查,所以是不安全的。

②用於基本資料型別之間的轉換,如把int轉換成char,把int轉換成enum。這種轉換的安全性也要開發人員來保證。

③把空指標轉換成目標型別的空指標。

④把任何型別的表示式轉換成void型別。

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

C++中static_cast和reinterpret_cast的區別

C++ primer第五章裡寫了編譯器隱式執行任何型別轉換都可由static_cast顯示完成;reinterpret_cast通常為運算元的位模式提供較低層的重新解釋

1、C++中的static_cast執行非多型的轉換,用於代替C中通常的轉換操作。因此,被做為顯式型別轉換使用。比如:

int i;
float f = 166.71;
i = static_cast<int>(f);

此時結果,i的值為166。

2、C++中的reinterpret_cast主要是將資料從一種型別的轉換為另一種型別。所謂“通常為運算元的位模式提供較低層的重新解釋”也就是說將資料以二進位制存在形式的重新解釋。比如:

int i;
char *p = "This is an example.";
i = reinterpret_cast<int>(p);

此時結果,i與p的值是完全相同的。reinterpret_cast的作用是說將指標p的值以二進位制(位模式)的方式被解釋為整型,並賦給i,//i 也是指標,整型指標;一個明顯的現象是在轉換前後沒有數位損失

C++同時提供了4種新的強制型別轉換形式(通常稱為新風格的或C++風格的強制轉 型):const_cast(expression)、dynamic_cast(expression)、 reinterpret_cast(expression)和 static_cast(expression),每一種都適用於特定的目的,具體如下:

(1)dynamic_cast 主要用於執行“安全的向下轉型(safe downcasting)”,也就是說,要確定一個物件是否是一個繼承體系中的一個特定型別。支援父類指標到子類指標的轉換,這種轉換時最安全的轉換。它 是唯一不能用舊風格語法執行的強制型別轉換,也是唯一可能有重大執行時代價的強制轉換。

(2)static_cast 可以被用於強制隱形轉換(例如,non-const物件轉換為const物件,int轉型為double,等等),它還可以用於很多這樣的轉換的反向轉換 (例如,void*指標轉型為有型別指標,基類指標轉型為派生類指標),但是它不能將一個const物件轉型為non-const物件(只有 const_cast能做到),它最接近於C-style的轉換。應用到類的指標上,意思是說它允許子類型別的指標轉換為父類型別的指標(這是一個有效的隱式轉換),同時,也能夠執行相反動作:轉換父類為它的子類。

在這最後例子裡,被轉換的父類沒有被檢查是否與目的型別相一致。 程式碼: 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)const_cast一般用於強制消除物件的常量性。它是唯一能做到這一點的C++風格的強制轉型。這個轉換能剝離一個物件的const屬性,也就是說允許你對常量進行修改。

程式碼: class C {}; const C *a = new C; C *b = const_cast<C *>(a);

(4)reinterpret_cast 是特意用於底層的強制轉型,導致實現依賴(就是說,不可移植)的結果,例如,將一個指標轉型為一個整數。這樣的強制型別在底層程式碼以外應該極為罕見。操作 結果只是簡單的從一個指標到別的指標的值得二進位制拷貝。在型別之間指向的內容不做任何型別的檢查和轉換。

舊風格 的強制轉型依然合法,但是新的形式更可取。首先,在程式碼中它們更容易識別(無論是人還是像grep這樣的工具都是如此),這樣就簡化了在程式碼中尋找型別系 統被破壞的地方的過程。其次,更精確地指定每一個強制轉型的目的,使得編譯器診斷使用錯誤成為可能。例如,試圖使用一個const_cast以外的新風格 強制轉型來消除常量性,程式碼將無法編譯。