C 4種型別轉換詳解

2021-06-22 05:46:53 字數 2892 閱讀 7080

在c/c++語言中用 

(type) value

(在c++還可以採用type(value))來進行顯式型別轉換(explicit type conversion),常常又被稱為強制轉換(cast投射/鑄模)。這種轉換的正確性完全掌握在程式設計師手中,傳統上強制轉換往往被過度使用,成為c++程式犯錯的乙個主要根源。

為了減少強制轉換的***,並且在查錯時使程式設計師能夠快速定位(總是最值得懷疑的)強制轉換,在標準c++中新增加了4個關鍵字*_cast,用來提倡一種全新的c++顯式轉換語法:

*_cast (expression)

l         static_cast(靜態轉換):用於明確定義良性和適度良性的轉換,包括原來不需要採用強制轉換的自動型別轉換(包括無損的提公升轉換和可能丟失資訊的窄化轉換[narrowing conversion],對後者編譯器一般會提出警告)。標準c++提倡對任何資料的型別轉換(不論是自動的還是強制的),都採用新的*_cast顯式型別轉換方法。例如:

int i = 0x7fff;

long l;

float f;

char c;

// (1)典型的非強制轉換(自動轉換)

// 傳統方式:

l = i;

f = i;

// 提倡的新方式:

l = static_cast(i);

f = static_cast(i);

// (2)窄化轉換

// 傳統方式:

// 會顯示警告資訊:

i = l; // 可能丟失數字

i = f; // 可能丟失資訊

c = i; // 可能丟失數字

// 不顯示警告資訊(但仍然難定位):

i = (int)l;

i = (int)f;

c = (char)i;

// 提倡的新方式(不會顯示警告資訊,且易定位):

i = static_cast(l);

i = static_cast(f);

c = static_cast(i);

l         const_cast(常量轉換):可將(同資料型別的)常型(const)轉換為非常型、將易變(volatile)型轉換為非易變型。如果用於其他型別的轉換,一般會產生乙個編譯錯誤。例如:

const int i = 0;

int *pi;

pi = &i; // 錯誤

pi = (int *)&i; // 被反對

pi = const_cast(&i); // 完美

long *pl = const_cast(&i); // 錯誤

volatile int k = 0;

int *pk = const_cast(&k); // 正確

l         dynamic_cast(動態轉換):一種安全的向下型別轉換(downcast)操作,用於在乙個類繼承層次上向下移動。

因為每個派生類的基類都只有乙個,而且派生類本身又包含了幾乎所有的基類資訊(private型的除外),所以向上的型別轉換(upcast)總是唯一的和比較安全的。

而乙個基類往往有多個派生類,而且派生類中一般會在基類的基礎上新增了一些特有的資料和操作,所以向下的型別轉換總是多型的和不太安全的。

dynamic_cast提供了一種安全的向下型別轉換操作,只有當型別轉換是正確的並且轉換取的成功,返回值才是所需要的指標;否則它將返回0(空指標null),表示不是正確的型別。

例如:class pet ;

class dog : public pet ;

class cat : public pet ;

……pet *ppet = new cat; // 向上的型別轉換

dog *pdog = dynamic_cast(ppet); // 型別錯誤,返回0(null)

cat *pcat = dynamic_cast(ppet); // 型別正確,返回指標

cat *pcat = static_cast(ppet); // 正確,減少執行時的開銷

注意:dynamic_cast雖然安全,但是執行時需要一定開銷,因此不提倡大量使用這種轉換。如果你已經能夠確認轉換的正確性,則可以採用前面介紹過的(無執行時開銷的)static_cast轉換。只有當你實在無法確定轉換是否正確時,才需要採用dynamic_cast轉換。

l         reinterpret_cast(重解釋轉換):一種最有可能出問題的最不安全的型別轉換。只是在下面的情形,才需要使用這種型別轉換:當需要使用時,所得到的東西已經不同了,為了使它能夠用於原來的目的,必須再次把它轉換回來。例如:

const int sz = 100; // 定義陣列大小,標準c++提倡用常型變數(而不是常數或

// 符號常量巨集)

struct x ; // 只包含乙個整數陣列的結構

x x; // 定義結構變數,此時結構中的陣列元素的值無意義(需要初始化)

int *px = reinterpret_cast(&x); // 為了初始化,先把結構轉化為int陣列

for (int *i = px; i < px + sz; i++) *i = 0; // 將每個陣列元素的值初始化為0

print(reinterpret_cast(px)); // 重新轉換成結構指標,以便使用

// 也可以直接使用原來的識別符號x

// 此語句相當於print(&x);

使用reinterpret_cast通常是一種不明智且不方便的程式設計方式。但是在必須使用時,它也是非常有用的。

在這四種強制轉換中,

static_cast

最常用(目前還沒有流行起來,但是被標準

c++著力提倡)、

dynamic_cast

最重要、

const_cast

也有用、而

reinterpret_cast

則很少被使用。

C 4種型別轉換

c 型別轉換 const cast,去const屬性。static cast,靜態型別轉換。如int轉換成char。dynamic cast,動態型別轉換。如子類和父類之間的多型型別轉換。reinterpret cast,僅僅重新解釋型別,但沒有進行二進位制的轉換。const cast const ...

C 4種型別轉換

總 結 去const屬性用const cast。基本型別轉換用static cast。多型類之間的型別轉換用daynamic cast。不同型別的指標型別轉換用reinterpreter cast。任何具有明確定義的型別轉換,只要不包含底層const,都可以使用static cast 注 頂層con...

C 4種強制型別轉換

c 的四種強制型別轉換為 static cast const cast reinterpret cast和dynamic cast 型別轉換的一般形式 cast name expression 任何具有明確定義的型別轉換,只要不包含底層const,都可以使用static cast double sl...