2011-12-26 138 views
4

可能重複:
When should static_cast, dynamic_cast and reinterpret_cast be used?C++鑄造運營商和傳統的C鑄造運營商

我已經做了google搜索找到有關的很多:

  1. 爲什麼要使用C++鑄造操作員比傳統的C風格鑄造操作員?
  2. 何時使用C++轉換操作符,一些活生生的實例?

以下是我發現:

  • 傳統上的任何C++轉換操作符,用於更好的維護您的代碼(即),我們不難發現其中的鑄造通過在代碼只是在尋找這個曾經複雜的符號(reinterpret_cast <)不像C風格的鑄造操作符。

現在讓我簡要說明爲什麼當每個C++轉換操作符

的static_cast的:

爲什麼使用對C風格的鑄造? static_cast用於相關類型之間的轉換。

例子:

Class A {}; 
Class B {}; 

A* a = new A(); 
B* b = static_cast<B*>(a); // Compiler error 
B* b1 = (A*)a; // Works fine 
float f; 
int addr = (int)(&f); // Works fine 
int addr = static_cast<int>(&f); // Compiler error 

但我想知道何時使用上面的代碼真正的用例?

的reinterpret_cast:

reinterpret_cast蒙上指向不相關的類型。

例子:

Class A {}; 
Class B {}; 

A* a = new A(); 
B* b = reinterpret_cast<B*>(a); // Works fine 
B* b1 = (A*)a; // Works fine 
float f; 
int addr = (int)(&f); // Works fine 
int addr = reinterpret_cast<int>(&f); // Works fine 


int ai = 10; 
float af = 13.33; 
// Would depend on how floating point is stored in machine 
// int& since reinterpret_cast expects either the type or operand to be pointer or reference 
int ki = reinterpret_cast<int&>(af); // ki would not be 13 
int kitemp = (int)af; // kitemp would be 13 

// The same reinterpret_cast behaviour can be achieved using this, 
int* in = (int*)(af); 
cout << (*in); 

我的問題是怎麼回事,是由C風格的鑄造reinterpret_cast不同?我無法找到與傳統鑄造操作員一起使用它的原因,以及何時使用它?

這使得這些運營商更糟另一個重要的例子是:

const unsigned int * p; 
    (int*)p; // Would remove unsigned and const at one shot 
    // Using C++ casting operators 
    // Const_cast expects a pointer or a reference 
    reinterpret_cast<int*>(const_cast<unsigned int* >(p)); 

編寫上述代碼除去constunsigned要複雜得多在C++鑄造?那麼,爲什麼人們使用reinterpret_castconst_caststatic_cast在土產Ç鑄造運營商?

我明白約dynamic_cast在多態類的情況下使用;這個運營商也有額外的RTTI費用。

+2

C++轉換是C風格演員的限制版本,它試圖幾乎每一個演員,直到它找到一個作品。當您想要進行某種類型的轉換時,應該使用C++樣式類型轉換,並且如果無法執行該類型的轉換,則編譯將失敗,其中C類型轉換用於「只做」轉換。 – 2011-12-26 06:20:35

+0

@Mat:從你建議的鏈接中,我瞭解了很多。但我在下面有一個疑問,你如何將這種類型的例子映射到C風格的鑄造,float a = 13.33; int b = reinterpret_cast (a); ...請讓我明白這個 – 2011-12-26 07:28:52

+0

@RishiMehta:我不知道該演員應該扮演什麼角色_mean_。你爲什麼要寫這樣的「東西」? – Mat 2011-12-26 08:43:56

回答

7

Google's C++ Style Guide給出了一些動機使用C++風格的轉換:

與C類型轉換問題在於操作的歧義;有時 您正在進行轉換(例如,(int)3.5),有時候您在 正在進行轉換(例如(int)"hello"); C++強制避免這種情況。另外 C++強制轉換在搜索它們時更加明顯。

我喜歡C++類型轉換,因爲它們使你打算做得非常明確,允許編譯器捕捉不正確的用法。

例如,如果您知道您只想對整數進行數值轉換,則static_cast僅在數值轉換有意義時纔會編譯。正如您在示例代碼中所展示的,C風格轉換將執行轉換,而不管其有效性。

C++類型轉換實際上只是爲了更好地記錄意圖和編譯時防止意外使用。

+0

+1的友好鏈接 – 2011-12-26 06:41:45

+0

是的..該鏈接是非常值得學習.. 。但是,如果使用C++類型轉換的話,你能幫助我嗎? – 2011-12-26 06:57:52

+0

我添加了一些到我的答案。這有幫助嗎?如果您還有其他問題,我可以給出更確切的例子。 – 2011-12-26 07:12:46

0

刪除const限定符是個壞習慣。您可能最終會寫入您不應寫入的內存變量或區域。因此,你的問題的一部分無效。

0

從我的記憶來看,reinterpret_cast和c風格演員幾乎是一樣的,除非我認爲如果你有一個const Thing你不能reinterpret_cast noncost_other_thing(c stye讓你刪除它們,這可能不是故意的,可能是危險的) 。

我只在自己的項目中使用c鑄造,因爲我有奢侈的懶惰,有時我不會懶惰。在使用C++時,你'假設'使用C++風格的轉換和其他C++特性(ostream而不是文件,沒有printf,避免memset和其他不安全的函數等)。但大多數人只是做他們想做的事情(並因此而得到錯誤)。

通常情況下,如果您知道何時使用dynamic_cast和靜態轉換,您將會很好。我發現reinterpret_cast不可能,除非我與C接口並需要使用void *。 const_cast ...我從來沒有使用過,希望我永遠不需要。你應該「總是使用它們。

PS:不相關的說明。我實際上拋出異常並斷言(0)未實現的東西。如果我不處理一個參數,並期望它是一個0我會寫一個異常或斷言檢查。當我調試/添加更多的代碼,我跑到這些而不是錯誤和theres絕對沒有神祕爲什麼它發生:)