簡體   English   中英

在現代C ++應用程序中使用Win32代碼時,是否應該使用正確的轉換?

[英]When using Win32 code in your modern C++ app, should you use proper casting?

例如,可以在整個MSDN文檔中找到以下演員:

(LPTSTR)&lpMsgBuf

我應該把它轉換成:

static_cast<LPTSTR>(&lpMsgBuf);

或者我應該留下所有慣用的C-esque Win32部分,因為它們通常在文檔中找到,並為我的其余代碼保存更慣用的C ++樣式/用法?

引入新風格的演員有一個原因:它們更安全,更具說明性/自我評論,更容易看到,更容易上映。

所以使用它們。

通過更多的解釋,我們的意思是你不能只是投射到什么,你必須說你為什么要投射(我在一個繼承層次結構(dynamic_cast)中投射,我的演員是實現定義的並且可能不是可移植的(reinterpret_cast) ,我正在拋棄constness(const_cast)等。

他們故意長而丑,以便演員跳出讀者(並阻止采用過多演員的編程風格)。

它們更安全,因為,例如,如果沒有明確地這樣做,你就不能拋棄const。

我沒有使用舊式強制轉換或新式強制轉換,而是利用C ++的運算符重載來添加帶有正確類型參數的Windows API函數的內聯重載版本。 (只要這是為新開發人員記錄的,它希望不會太混亂。)

例如, FormatMessage的第五個參數通常是LPTSTR ,但是如果傳遞FORMAT_MESSAGE_ALLOCATE_BUFFER標志,則第五個參數是指向LPTSTR的指針。 所以我定義了一個這樣的函數:

inline DWORD WINAPI FormatMessage(
  __in      DWORD dwFlags,
  __in_opt  LPCVOID lpSource,
  __in      DWORD dwMessageId,
  __in      DWORD dwLanguageId,
  __out     LPTSTR *lpBuffer,
  __in      DWORD nSize,
  __in_opt  va_list *Arguments
) {
    assert(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER);
    return FormatMessage(dwFlags, lpSource, dwMessageId, dwLanguageId, static_cast<LPTSTR>(&lpBuffer), nSize, Arguments);
}

MSDN文檔與C ++標准。

我會選擇后者。 我認為這也是有效C ++中討論的規則之一。 應該在一個程序中混合使用兩種風格。

你根本不應該需要一個lpMsgBuf - 從它的外觀來看, lpMsgBuf是一個指向字符數組的指針(如果它們是ANSI字符或寬字符,則從上下文中不清楚),你可以直接傳遞給各種Win32職能。

沒有必要獲取地址 - 如果lpMsgBuf是一個靜態數組(例如char lpMsgBuf[SIZE] ),那么獲取其地址是多余的,並且等同於其第一個元素的地址。 如果它是一個指針,那么獲取它的地址會產生一個char** (如果它是寬的則為wchar_t** ),這不是你想傳遞的 - 如果一個Win32函數期望一個LPSTR (即一個char* )和你將char**傳遞給char* ,會導致很多不好。 編譯器不允許將char**傳遞給期望沒有強制轉換的char*的函數 - 使用強制轉換使編譯器靜默,因為編譯器試圖告訴你重要的事情。

如果你不能在沒有強制轉換的情況下傳遞你想要的參數,你幾乎肯定會錯誤地傳遞它。 修復代碼,以便您不需要強制轉換。

如果lpMsgBuf已經是指向T字符串的指針,並且如果API期望指針直接指向T字符串,那么你根本不應該使用任何強制轉換。 換句話說,如果數據類型已經正確,那么最好不要使用不必要的強制轉換。 原因是過度使用強制轉換會在演員關閉編譯器的同時使你失去bug。

如果lpMsgBuf已經是一個指向T字符串的指針,並且如果API需要一個指向T字符串的指針,但是API期望指向指針的指針被轉換為指向T字符串的類型指針(並且API將它轉換為回來使用它的時候),那你就做對了。

如果lpMsgBuf是指向其他東西(正確類型)的指針,並且API期望指向指向您的類型的指針,但API期望這些轉換游戲,那么您正在做正確的事情。

如果lpMsgBuf是一個指向T字符串的指針,並且如果API需要一個指向T字符串的指針,那么通過使用&運算符,您將構建一個指向指向T字符串的指針,該指針是API不期望的,並且通過使用轉換,您告訴編譯器將指針轉換為指針指向T字符串的類型指針,即使該值仍指向指針。 因此,您成功關閉了編譯器,但仍然向您或您的客戶提供垃圾結果。

因此,如果沒有更多關於哪個MSDN頁面告訴您創建指針指針並為哪些API播放游戲的詳細信息,我們無法猜測您是否正確執行,或者您是否誤讀了MSDN,或者MSDN是否在告訴你寫錯了代碼。

現在,如果演員表實際上是正確的,那么選擇使用哪種語法取決於你在程序其余部分的樣式。

在大多數情況下,MSDN Win32示例代碼與C C ++兼容。 使用普通的舊C來編寫Windows程序是完全允許的(並且在某個時間點是標准做法)。

由於C ++強制轉換在C中不可用,因此修改示例以利用它們需要維護兩個示例代碼副本。 由於C代碼在C ++中工作,因此將舊樣式轉換更容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM