c 中的四種型別轉換的區別

2021-08-09 07:40:34 字數 4050 閱讀 6592

型別轉換有c風格的,當然還有c++風格的。c風格的轉換的格式很簡單

(type)expression;

但是c風格的型別轉換有不少的缺點,有的時候用c風格的轉換是不合適的,因為它可以在任意型別之間轉換,比如你可以把乙個指向const物件的指標轉換 成指向非const物件的指標,把乙個指向基類物件的指標轉換成指向乙個派生類物件的指標,這兩種轉換之間的差別是巨大的,但是傳統的c語言風格的型別轉 換沒有區分這些。還有乙個缺點就是,c風格的轉換不容易查詢,他由乙個括號加上乙個識別符號組成,而這樣的東西在c++程式裡一大堆。

所以c++為了克服這些缺點,引進了4新的型別轉換操作符,他們是,static_cast,const_cast,dynamic_cast,reinterpret_cast.

static_cast

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

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

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

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

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

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

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

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

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

c++中static_cast和reinterpret_cast的區別

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

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

int i; 

float f = 166.7f; 

i = static_cast(f); 

此時結果,i的值為166。 

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

int i; 

char *p = "this is a example."; 

i = reinterpret_cast(p);

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

reinterpret_cast

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

reinterpret_cast是c++裡的強制型別轉換符。

操作符修改了運算元型別,但僅僅是重新解釋了給出的物件的位元模型而沒有進行二進位制轉換。

例如:int *n= new int ;

double *d=reinterpret_cast(n);

在進行計算以後, d 包含無用值. 這是因為 reinterpret_cast 僅僅是複製 n 的位元位到 d, 沒有進行必要的分析。

因此, 需要謹慎使用 reinterpret_cast.

並且:reinterpret_cast 只能在指標之間轉換。

static_cast .vs. reinterpret_cast

static_cast 和 reinterpret_cast 操作符修改了運算元型別。它們不是互逆的; static_cast 在編譯時使用型別資訊執行轉換,在轉換執行必要的檢測(諸如指標越界計算, 型別檢查). 其運算元相對是安全的。另一方面;reinterpret_cast 僅僅是重新解釋了給出的物件的位元模型而沒有進行二進位制轉換, 例子如下:

int n=9; double d=static_cast < double > (n);

上面的例子中, 我們將乙個變數從 int 轉換到 double。 這些型別的二進位制表示式是不同的。 要將整數 9 轉換到 雙精度整數 9,static_cast 需要正確地為雙精度整數 d 補足位元位。其結果為 9.0。而reinterpret_cast 的行為卻不同:

int n=9;

double d=reinterpret_cast(n);

這次, 結果有所不同. 在進行計算以後, d 包含無用值. 這是因為 reinterpret_cast 僅僅是複製 n 的位元位到 d, 沒有進行必要的分析.

因此, 你需要謹慎使用 reinterpret_cast.

dynamic_cast

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

該運算子把expression轉換成type-id型別的物件。type-id必須是類的指標、類的引用或者void *;

如果type-id是類指標型別,那麼expression也必須是乙個指標,如果type-id是乙個引用,那麼expression也必須是乙個引用。

dynamic_cast主要用於類層次間的上行轉換和下行轉換,還可以用於類之間的交叉轉換。

在類層次間進行上行轉換時,dynamic_cast和static_cast的效果是一樣的;

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

class b;

class d:public b;

void func(b *pb)

在上面的**段中,如果pb指向乙個d型別的物件,pd1和pd2是一樣的,並且對這兩個指標執行d型別的任何操作都是安全的;

但是,如果pb指向的是乙個b型別的物件,那麼pd1將是乙個指向該物件的指標,對它進行d型別的操作將是不安全的(如訪問m_szname),

而pd2將是乙個空指標。

另外要注意:b要有虛函式,否則會編譯出錯;static_cast則沒有這個限制。

這是由於執行時型別檢查需要執行時型別資訊,而這個資訊儲存在類的虛函式表

關於虛函式表的概念,詳細可見)中,只有定義了虛函式的類才有虛函式表,

沒有定義虛函式的類是沒有虛函式表的。

另外,dynamic_cast還支援交叉轉換(cross cast)。如下**所示。

class a

};class b:public a;

class d:public a;

void foo()

在函式foo中,使用static_cast進行轉換是不被允許的,將在編譯時出錯;而使用 dynamic_cast的轉換則是允許的,結果是空指標。

const_cast

用法:const_cast(expression)

該運算子用來修改型別的const或volatile屬性。除了const 或volatile修飾之外, type_id和expression的型別是一樣的。

常量指標被轉化成非常量指標,並且仍然指向原來的物件;

常量引用被轉換成非常量引用,並且仍然指向原來的物件;常量物件被轉換成非常量物件。

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

class b

void foo()

上面的**編譯時會報錯,因為b1是乙個常量物件,不能對它進行改變;

C 中四種型別轉換的區別

型別轉換有c風格的,當然還有c 風格的。c風格的轉換的格式很簡單 type expression,但是c風格的型別轉換有不少的缺點,有的時候用c風格的轉換是不合適的,因為它可以在任意型別之間轉換,比如你可以把乙個指向const物件的指標轉換成指向非const物件的指標,把乙個指向基類物件的指標轉換成...

c 中的四種型別轉換的區別

型別轉換有c風格的,當然還有c 風格的。c風格的轉換的格式很簡單 type expression 但是c風格的型別轉換有不少的缺點,有的時候用c風格的轉換是不合適的,因為它可以在任意型別之間轉換,比如你可以把乙個指向const物件的指標轉換 成指向非const物件的指標,把乙個指向基類物件的指標轉換...

C 中的四種型別轉換

static cast type id expression 1 基本型別之間的轉換 如把int轉換成char,這種轉換的安全性也要開發人員來保證。但不能用於不同指標型別之間的型別轉換。static cast更有利於檢查出危險的型別轉換。float af 3.0f double pdouble st...