強制型別轉換 (c primer)

2021-06-21 15:46:47 字數 3048 閱讀 5677

命名的強制型別轉換符號的一般形式如下:

cast-name(expression);

其中 cast-name 為 static_cast、dynamic_cast、const_cast 和reinterpret_cast 之一,type 為轉換的目標型別,而 expression 則是被強制轉換的值。強制轉換的型別指定了在 expression 上執行某種特定型別的轉換。

dynamic_cast 支援執行時識別指標或引用所指向的物件。

const_cast ,顧名思義,將轉換掉表示式的 const 性質。例如,假設有函式 string_copy,只有唯一的引數,為 char* 型別,我們對該函式唯讀不寫。在訪問該函式時,最好的選擇是修改它讓它接受 const char* 型別的引數。如果不行,可通過 const_cast 用乙個 const 值呼叫 string_copy 函式:

const char *pc_str;

char *pc = string_copy(const_cast(pc_str));

只有使用 const_cast 才能將 const 性質轉換掉。在這種情況下,試圖使用其他三種形式的強制轉換都會導致編譯時的錯誤。類似地,除了新增或刪除 const 特性,用 const_cast 符來執行其他任何型別轉換,都會引起編譯錯誤。

編譯器隱式執行的任何型別轉換都可以由 static_cast 顯式完成:

double d = 97.0;

// cast specified to indicate that the conversion is intentional

char ch = static_cast(d);

當需要將乙個較大的算術型別賦值給較小的型別時,使用強制轉換非常有用。此時,強制型別轉換告訴程式的讀者和編譯器:我們知道並且不關心潛在的精度損失。對於從乙個較大的算術型別到乙個較小型別的賦值,編譯器通常會產生警告。當我們顯式地提供強制型別轉換時,警告資訊就會被關閉。

如果編譯器不提供自動轉換,使用 static_cast 來執行型別轉換也是很有用的。例如,下面的程式使用 static_cast 找回存放在 void* 指標中的值(第 4.2.2 節):

void* p = &d; // ok: address of any data object can be stored in a

void*

// ok: converts

void*

back to the original pointer type

double *dp = static_cast(p);

可通過 static_cast 將存放在 void* 中的指標值強制轉換為原來的指標型別,此時我們應確保保持指標值。也就是說,強制轉換的結果應與原來的位址值相等。

reinterpret_cast 通常為運算元的位模式提供較低層次的重新解釋。

注意:

reinterpret_cast 本質上依賴於機器。為了安全地使用 reinterpret_cast,要求程式設計師完全理解所涉及的資料型別,以及編譯器實現強制型別轉換的細節。

強制型別轉換關閉或掛起了正常的型別檢查。強烈建議程式設計師避免使用強制型別轉換,不依賴強制型別轉換也能寫出很好的 c++ 程式。

這個建議在如何看待 reinterpret_cast 的使用時非常重要。此類強制轉換總是非常危險的。相似地,使用 const_cast 也總是預示著設計缺陷。設計合理的系統應不需要使用強制轉換拋棄 const 特性。其他的強制轉換,如 static_cast 和 dynamic_cast,各有各的用途,但都不應頻繁使用。每次使用強制轉換前,程式設計師應該仔細考慮是否還有其他不同的方法可以達到同一目的。如果非強制轉換不可,則應限制強制轉換值的作用域,並且記錄所有假定涉及的型別,這樣能減少錯誤發生的機會。

在引入命名的強制型別轉換操作符之前,顯式強制轉換用圓括號將型別括起來實現:

char *pc = (char*) ip;
在引入命名的強制型別轉換操作符之前,顯式強制轉換用圓括號將型別括起來實現:

char *pc = (char*) ip;

效果與使用 reinterpret_cast 符號相同,但這種強制轉換的可視性比較差,難以跟蹤錯誤的轉換。

標準 c++ 為了加強型別轉換的可視性,引入命名的強制轉換操作符,為程式設計師在必須使用強制轉換時提供了更好的工具。例如,非指標的 static_cast 和 const_cast 要比 reinterpret_cast 更安全。結果使程式設計師(以及讀者和操縱程式的工具)可清楚地辨別**中每個顯式的強制轉換潛在的風險級別。

雖然標準 c++ 仍然支援舊式強制轉換符號,但是我們建議,只有在 c 語言或標準 c++ 之前的編譯器上編寫**時,才使用這種語法。

舊式強制轉換符號有下列兩種形式:

type (expr); // function-style cast notation

(type) expr; // c-language-style cast notation

舊式強制轉換依賴於所涉及的資料型別,具有與 const_cast、 static_cast 和 reinterpret_cast 一樣的行為。在合法使用 static_cast 或 const_cast 的地方,舊式強制轉換提供了與各自對應的命名強制轉換一樣的功能。如果這兩種強制轉換均不合法,則舊式強制轉換執行 reinterpret_cast 功能。例如,我們可用舊式符號重寫上一節的強制轉換:

int ival; double dval;

ival += int (dval); // static_cast:

converts

double

toint

const char* pc_str;

string_copy((char*)pc_str); // const_cast:

casts away

const

int *ip;

char *pc = (char*)ip; // reinterpret_cast:

treats

int*

aschar*

支援舊式強制轉換符號是為了對「在標準 c++ 之前編寫的程式」保持向後相容性,並保持與 c 語言的相容性。

《C primer》 中 強制型別轉換

命名的強制型別轉換符號一般形式如下 cast name expression 其中cast name為static cast,dynamic cast,const cast,reinterpret cast之一,type為轉換目標,而expression為被強制型別轉換的值。強制轉換的型別指定了在e...

強制型別轉換

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

強制型別轉換

顯式轉換也稱為強制型別轉換 cast 包括以下列名字命名的強制型別轉換操作符 static cast dynamic cast const cast 和 reinterpret cast。命名的強制型別轉換符號的一般形式如下 cast name expression 其中 cast name 為 s...