c 強制型別轉換

2021-06-14 02:12:41 字數 4473 閱讀 7219

c++風格的型別轉換提供了4種型別轉換操作符來應對不同場合的應用。

const_cast:              主要針對const和volatile的轉換.

static_cast:              一般的轉換,no run-time check.通常,如果你不知道該用哪個,就用這個。

dynamic_cast:          通常在基類和派生類之間轉換時使用,run-time cast

reinterpret_cast:     用於進行沒有任何關聯之間的轉換,比如乙個字元指標轉換為乙個整形數。

1)const_cast(a)[/b]

編譯器在編譯期處理

去掉型別中的常量,除了const或不穩定的變址數,t和a必須是相同的型別。

表示式const_cast(a)被用於從乙個類中去除以下這些屬性:const, volatile, 和 __unaligned。

class a ;

void f()

對於本身定義時為const的型別,即使你去掉const性,在你操作這片內容時候也要小心,只能r不能w操作,否則還是會出錯

const char* p = "123";

char* c = const_cast(p);

c[0] = 1; //表面上通過編譯去掉了const性,但是操作其位址時系統依然不允許這麼做。

const_cast操作不能在不同的種類間轉換。相反,它僅僅把乙個它作用的表示式轉換成常量。它可以使乙個本來不是const型別的資料轉換成const型別的,或者把const屬性去掉。

盡量不要使用const_cast,如果發現呼叫自己的函式,竟然使用了const_cast,那就趕緊打住,重新考慮一下設計吧。

2)static_cast(a)[/b]

編譯器在編譯期處理

將位址a轉換成型別t,t和a必須是指標、引用、算術型別或列舉型別。

表示式static_cast(a), a的值轉換為模板中指定的型別t。在執行時轉換過程中,不進行型別檢查來確保轉換的安全性。

static_cast它能在內建的資料型別間互相轉換,對於類只能在有聯絡的指標型別間進行轉換。可以在繼承體系中把指標轉換來、轉換去,但是不能轉換成繼承體系外的一種型別

class a ;

class b ;

class d : public b ;

void f(b* pb, d* pd)

另外的一種解釋:

1. 基類和子類之間轉換:其中子類指標轉換成父類指標是安全的;但父類指標轉換成子類指標是不安全的。(基類和子類之間的動態型別轉換建議用dynamic_cast)

2. 基本資料型別轉換。enum, struct, int, char, float等。static_cast不能進行無關型別(如非基類和子類)指標之間的轉換。

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

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

5. static_cast不能去掉型別的const、volitale屬性(用const_cast)。

int n = 6;

double d = static_cast(n); // 基本型別轉換

int *pn = &n;

double *d = static_cast(&n) //無關型別指標轉換,編譯錯誤

void *p = static_cast(pn); //任意型別轉換成void型別

3)dynamic_cast(a)[/b]

在執行期,會檢查這個轉換是否可能。

完成類層次結構中的提公升。t必須是乙個指標、引用或無型別的指標。a必須是決定乙個指標或引用的表示式。

dynamic_cast 僅能應用於指標或者引用,不支援內建資料型別

表示式dynamic_cast(a) 將a值轉換為型別為t的物件指標。如果型別t不是a的某個基型別,該操作將返回乙個空指標。

它不僅僅像static_cast那樣,檢查轉換前後的兩個指標是否屬於同乙個繼承樹,它還要檢查被指標引用的物件的實際型別,確定轉換是否可行。

如果可以,它返回乙個新指標,甚至計算出為處理多繼承的需要的必要的偏移量。如果這兩個指標間不能轉換,轉換就會失敗,此時返回空指標(null)。

很明顯,為了讓dynamic_cast能正常工作,必須讓編譯器支援執行期型別資訊(rtti)。

有條件轉換,動態型別轉換,執行時型別安全檢查(轉換失敗返回null):

1. 安全的基類和子類之間轉換。

2. 必須要有虛函式。

3. 相同基類不同子類之間的交叉轉換。但結果是null。

class baseclass ;

//基類必須有虛函式。保持多台特性才能使用dynamic_cast

};class derivedclass: public baseclass ;

};baseclass* pb = new derivedclass();

derivedclass *pd1 = static_cast(pb);

//子類->父類,靜態型別轉換,正確但不推薦

derivedclass *pd2 = dynamic_cast(pb);

//子類->父類,動態型別轉換,正確

baseclass* pb2 = new baseclass();

derivedclass *pd21 = static_cast(pb2);

//父類->子類,靜態型別轉換,危險!訪問子類m_szname成員越界

derivedclass *pd22 = dynamic_cast(pb2);

//父類->子類,動態型別轉換,安全的。結果是null

4)reinterpret_cast(a)[/b]

編譯器在編譯期處理

任何指標都可以轉換成其它型別的指標,t必須是乙個指標、引用、算術型別、指向函式的指標或指向乙個類成員的指標。

表示式reinterpret_cast(a)能夠用於諸如char* 到 int*,或者one_class* 到 unrelated_class*等類似這樣的轉換,因此可能是不安全的。

class a ;

class b ;

void f()

使用reinterpret_cast 的場合不多,僅在非常必要的情形下,其他型別的強制轉換不能滿足要求時才使用。

static_cast 和 reinterpret_cast 操作符修改了運算元型別。它們不是互逆的;

static_cast 在編譯時使用型別資訊執行轉換,在轉換執行必要的檢測(諸如指標越界計算, 型別檢查). 其運算元相對是安全的。

另一方面;reinterpret_cast是c++裡的強制型別轉換符,操作符修改了運算元型別,但僅僅是重新解釋了給出的物件的位元模型而沒有進行二進位制轉換。

例子如下:

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.

reinterpret_casts的最普通的用途就是在函式指標型別之間進行轉換。

例如,假設你有乙個函式指標陣列:

typedefvoid(*funcptr)();//funcptr is乙個指向函式的指標,該函式沒有引數,返回值型別為void

funcptrfuncptrarray[10];//funcptrarray是乙個能容納10個funcptrs指標的陣列

讓我們假設你希望(因為某些莫名其妙的原因)把乙個指向下面函式的指標存入funcptrarray陣列:

int dosomething();

你不能不經過型別轉換而直接去做,因為dosomething函式對於funcptrarray陣列來說有乙個錯誤的型別。在funcptrarray陣列裡的函式返回值是void型別,而dosomething函式返回值是int型別。

funcptrarray[0] = &dosomething;//錯誤!型別不匹配

reinterpret_cast可以讓你迫使編譯器以你的方法去看待它們:

funcptrarray[0] = reinterpret_cast(&dosomething);

轉換函式指標的**是不可移植的(c++不保證所有的函式指標都被用一樣的方法表示),在一些情況下這樣的轉換會產生不正確的結果.

總 結去const屬性用const_cast。

基本型別轉換用static_cast。

多型類之間的型別轉換用daynamic_cast。

不同型別的指標型別轉換用reinterpreter_cast。

C 強制型別轉換

四種型別可能很多人都常常忽略就象我一樣,但是有時還是比較有用的。不了解的建議看看,一些機制我也不是十分了解,只是將一些用法寫出來讓大家看看。強制轉化無論從語法還是語意上看,都是c 中最難看的特徵之一。但是基於c風格的轉化的語義的不明確性及其一些潛在問題。強制型別轉化最終還是被c 接受了。1.stat...

C 強制型別轉換

標準c 中主要有四種強制轉換型別運算子 const cast,reinterpret cast,static cast,dynamic cast等等。1 static cast a 將位址a轉換成型別t,t和a必須是指標 引用 算術型別或列舉型別。表示式static cast a a的值轉換為模板中...

C 強制型別轉換

關於強制型別轉換的問題,很多書都討論過,寫的最詳細的是c 之父的 c 的設計和演化 最好的解決方法就是不要使用c風格的強制型別轉換,而是使用標準c 的型別轉換符 static cast,dynamic cast。標準c 中有四個型別轉換符 static cast,dynamic cast,reint...