[英]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.