c 強制型別轉換

2021-08-20 08:07:53 字數 3459 閱讀 4069

一、static_cast:

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

(1)用於基本資料型別之間的轉換,如把int轉換為char,把int轉換成enum,但這種轉換的安全性需要開發者自己保證(這可以理解為保證資料的精度,即程式設計師能不能保證自己想要的程式安全),如在把int轉換為char時,如果char沒有足夠的位元位來存放int的值(int>127或int

比如下面的例子:int轉換為short時,直接把低十六位暫存器ax中的位拷貝到c。

(2)把空指標轉換成目標型別的空指標

(3)把任何型別的表示式型別轉換成void型別

(4)用於類層次結構中父類和子類之間指標和引用的轉換。

對於以上第(4)點,存在兩種形式的轉換,即上行轉換(子類到父類)和下行轉換(父類到子類)。對於static_cast,上行轉換時安全的,而下行轉換時不安全的,為什麼呢?因為static_cast的轉換時粗暴的,它僅根據型別轉換語句中提供的資訊(尖括號中的型別)來進行轉換,這種轉換方式對於上行轉換,由於子類總是包含父類的所有資料成員和函式成員,因此從子類轉換到父類的指標物件可以沒有任何顧慮的訪問其(指父類)的成員。而對於下行轉換為什麼不安全,是因為static_cast只是在編譯時進行型別堅持,沒有執行時的型別檢查。

二、const_cast:

作用:用來強制移除變數的cv屬性(這裡我們只討論const屬性)。

int i = 1; //改為const int i;

cout

<< "i turns out to be: "

<< i << endl;

const

int* pc = &i;

int* modifier = const_cast

(pc);

*modifier = 2;

cout

<< "i now is: "

<< i << endl;

cout

<< "*modifier is : "

<< *modifier << endl;

結果:

如果上例第一句是const int i = 1;那麼再按照這種方式去修改i的值將會產生未定義行為!

其實,const_cast最主要是應用在函式過載中。《effective c++》中有個很好的例子:

class textblock

char& operator(size_t position)

//...

private:

string text;

//...

};

三、reinterpret_cast:

作用:用來處理無關型別之間的轉換;它會產生乙個新的值,這個值會有與原始引數(expressoin)有完全相同的位元位(位元位的重新解釋)。

濫用 reinterpret_cast 運算子可能很容易帶來風險。 除非所需轉換本身是低階別的,否則應使用其他強制轉換運算子之一。

reinterpret_cast 運算子可用於 char* 到 int* 或 one_class* 到 unrelated_class* 之類的轉換,這本身並不安全。

reinterpret_cast 的結果不能安全地用於除強制轉換回其原始型別以外的任何用途。 在最好的情況下,其他用途也是不可移植的。

reinterpret_cast 運算子不能丟掉 const、volatile 或 __unaligned 特性。

reinterpret_cast 運算子將 null 指標值轉換為目標型別的 null 指標值。

reinterpret_cast 的乙個實際用途是在雜湊函式中,即,通過讓兩個不同的值幾乎不以相同的索引結尾的方式將值對映到索引。

#include 

using

namespace

std;

// returns a hash code based on an address

unsigned

short hash( void *p )

using

namespace

std;

int main()

四、dynamic_cast:

使用形式如下:

dynamic_cast

(e); //e是有效指標

dynamic_cast

(e); //e是左值

dynamic_cast

(e);//e是右值

type是類型別且通常含有虛函式。e的型別是以下3中情況之一:

即能進行的轉換是:

向上轉型是多型的基礎,需不要借助任何特殊的方法,只需用將子類的指標或引用賦給基類的指標或引用即可,當然dynamic_cast(static_cast)也支援向上轉型,而其總是肯定成功的。

對於指標的「向下轉型」有兩種情況。一種是基類指標所指物件是派生類型別的,這種轉換是安全的;另一種是基類指標所指物件為基類型別,在這種情況下dynamic_cast在執行時做檢查,轉換失敗,返回結果為0;

class base

; virtual

void show()

};class derived:public base

; void show()

}; //這是第一種情況

base* base = new derived;

if(derived *der= dynamic_cast

(base))

else

{cout

<

也可以使用dynamic_cast將基類引用轉換為派生類引用,同樣的,引用的向上轉換總是安全的;與指標一樣,引用的向下轉型也可以分為兩種情況,與指標不同的是,並不存在空引用,所以引用的dynamic_cast檢測失敗時會丟擲乙個bad_cast異常。

使用dynamic_cast轉換的base類至少帶有乙個虛函式。

乙個例題:

//假如有繼承關係:a

a* a = new c; // 本質

b* b = dynamic_cast

(a); // 成功,因為b是c的父類

e* e = dynamic_cast

(a); // 失敗,因為e是c的子類,返回空指標

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...