2010-02-27 141 views
12

我一直在閱讀很多關於C++的鑄造,我開始感到困惑,因爲我一直使用C風格鑄造。混淆C++鑄造

我已經讀過C風格的鑄造應該避免在C++中,並reinterpret_cast是非常非常危險的,不應該有任何替代時使用。與不使用reinterpret_cast相反,我已經在他們的示例代碼中看到了它在MSDN上多次使用。這讓我問我的第一個問題,什麼時候可以使用reinterpret_cast?

例如:

LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (Msg) 
    { 
     case WM_CREATE: 
     { 
      LPCREATESTRUCT lpCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); 
      return 0; 
     } 
    } 

    ... 
} 

如果這也不行,那我將如何只使用靜態,動態和/或const鑄造LPARAM值轉換爲指針?

另外:如果reinterpret_cast的是不可移植的,我怎麼會重寫它是便攜式的(良好做法)

+1

這可能是非常舊的代碼庫。 – 2010-02-27 00:50:48

回答

8

使用的reinterpret_cast是可以接受的,如果你知道指針最初目標類型。任何其他用途都利用了依賴於實現的行爲,儘管在許多情況下這是必要且有用的,例如將指向結構的指針轉換爲指向字節的指針,以便可以對其進行序列化。

它被認爲是危險的,因爲它不會在編譯時或運行時檢查。如果你犯了一個錯誤,它會崩潰並燒燬,而且很難調試。你基本上告訴編譯器「我比你更瞭解這個實際情況,所以只需編譯代碼,讓我擔心後果。」

+1

以這種方式序列化結構是一個壞主意(即使經常完成),但這是另一個問題的主題。 – Tronic 2010-02-27 01:50:06

5

你看到它在MSDN的原因是因爲Win32 API是ç API,但人們堅持讓步C++例子。

當您編寫與其他庫接口的代碼時,重新解析轉換是很好的。應該在您自己的應用程序內避免

2

不是不尊重MSDN,但MSDN不是適合C++編碼的最佳選擇。

使用reinterpret_cast的一個原因是當您向/從不透明數據類型轉換/時。 reinterpret_cast不是「危險的」,它只是很容易搞砸並導致代碼中的問題,這就是爲什麼它應該被避免。

爲什麼C++風格強制類型首選的原因是,static_cast是類型安全的,並且所有強制轉換時間都更容易搜索。

程序員[不正確]經常使用強制轉換來「擺脫編譯器警告」,如從無符號轉換爲有符號整數,或者從32位整數轉換爲8位整數。

+1

+1。 MSDN充滿了MS-ISMS。 Scott Meyers和Herb Sutter的好書(儘管他現在在MS,他是一位出色的作家,並且在編寫優秀的C++方面有很多偉大的建議)是鞏固自己對良好C++實踐的理解的好地方。 – 2010-02-27 01:15:37

+0

@Matt Curtis - 我覺得MSDN中比較煩人的部分是MS-isms不一致的應用。他們的例子質量差異很大。但一般來說,你不應該複製他們的例子;它可能會給你一個粗略的想法,但你應該將這些想法適應於你正在使用的項目中使用的任何編碼風格。 – asveikau 2010-02-27 01:53:59

2

本質reinterpret_cast是「安全」與C結構和基本類型(霸菱平原錯誤,類似於鑄造int的指針和背部,這在ILP32架構,但在LP64一個休息的作品。)AC結構不會有任何東西,除了可能用於對齊的填充,您沒有聲明。之類的東西指向虛表指向虛基類 -

reinterpret_cast因爲編譯器插入數據項到你的類不能與C++多態類型安全。其他C++類型轉換可以在從指針向基類向指向派生類的指針下注時調整這些值,reinterpret_cast和C風格類型轉換不會。

3

這是一個使用C++編程Windows平臺SDK(C API)的示例。該窗口過程只有WPARAM和LPARAM參數,並且如果需要通過窗口消息將指針傳遞給結構,則必須進行強制轉換。在我看來,這是reinterpret_cast <>的完全可接受的用法。您無法避免投射,因爲您要寫入的SDK不是您的代碼,並非針對C++設計的,更不用說類型安全性,並且需要使用C綁定來提供泛型參數類型。

reinterpret_cast <>這裏是一個標誌,讓你知道你需要小心,但它不是不惜一切代價避免。

另一方面,如果您控制代碼的雙方,API和消費者,那麼最好製作一個類型安全的API,並且不需要消費者執行強制轉換以使用它正確。