例如,在整个MSDN文档中可以找到以下演员:
(LPTSTR)&lpMsgBuf
我是否应该将其转换为:
static_cast<LPTSTR>(&lpMsgBuf);
或者我应该留下所有惯用的C-esque Win32部分,因为它们通常在文档中找到,并为我的其余代码保存更惯用的C ++样式/用法?
答案 0 :(得分:12)
引入新风格的演员有一个原因:它们更安全,更具说明性/自我评论,更容易看到,更容易上映。
所以使用它们。
通过更多的解释,我们的意思是你不能只是投射到某些东西,你必须说为什么你正在投射(我在一个继承层次结构(dynamic_cast)中投射,我的演员表是实现定义的,可能不是可移植的(reinterpret_cast),我正在抛弃constness(const_cast)等。
他们有目的地长而丑陋,以便演员跳出读者(并且阻止采用过多演员的编程风格)。
它们更安全,因为,例如,如果没有明确地这样做,你就不能抛弃const。
答案 1 :(得分:6)
我没有使用旧式强制转换或新式强制类型转换我的代码,而是利用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);
}
答案 2 :(得分:3)
MSDN文档与C ++标准版。
我会选择后者。我认为这也是有效C ++中讨论的规则之一。你应该不在一个程序中混合两种风格。
答案 3 :(得分:3)
你根本不需要演员 - 从它的外观来看,lpMsgBuf
是指向一个字符数组的指针(如果它们是ANSI字符或宽字符,则从上下文中不清楚),你可以直接传递给各种Win32函数。
如果lpMsgBuf
是静态数组(例如char lpMsgBuf[SIZE]
),则无需取地址,然后取其地址是多余的,等同于其第一个元素的地址。如果它是一个指针,那么获取它的地址会产生char**
(如果它是宽的话,则为wchar_t**
,这不是你想传递的 - 如果Win32函数期望{{1} (即LPSTR
)并将char*
强制转换为char**
,会导致很多不良。编译器不允许您将char*
传递给期望char**
而没有强制转换的函数 - 使用强制转换使编译器静默,因为编译器试图告诉您重要的事情。
如果你不能在没有强制转换的情况下传递你想要的参数,你几乎肯定会错误地传递它。修复代码,以便您不需要演员。
答案 4 :(得分:0)
如果lpMsgBuf已经是指向T字符串的指针,并且如果API期望指针直接指向T字符串,则根本不应该使用任何强制转换。换句话说,如果数据类型已经正确,那么最好不要使用不必要的强制转换。原因是过度使用强制转换可能会在演员关闭编译器的同时使你失去bug。
如果lpMsgBuf已经是指向T字符串的指针,并且API期望指向指向T字符串的指针,但API期望指向指针的指针被转换为指向T字符串的指针(以及API)在使用它时会把它丢回),然后你就做对了。
如果lpMsgBuf是指向其他东西(正确类型)的指针,并且API期望指向指向您的类型的指针,但API期望这些投射游戏,那么您就是这样做的。
如果lpMsgBuf是指向T字符串的指针,并且如果API需要指向T字符串的指针,那么通过使用&amp;运算符你正在构建一个指向指向T字符串的指针,这是指向API不期望的指针,并且通过使用转换,你告诉编译器将指针指向指向T字符串的指针,即使该值仍指向指针。因此,您成功关闭了编译器,但仍然向您或您的客户提供垃圾结果。
因此,如果没有更多关于哪个MSDN页面告诉您创建指针指针并为哪些API播放游戏的详细信息,我们无法猜测您是否正确行事,或者您是否误读了MSDN,或者是否MSDN告诉你编写错误的代码。
现在,如果演员表实际上是正确的,那么选择使用哪种语法取决于你在程序其余部分的风格。
答案 5 :(得分:0)
在大多数情况下,MSDN Win32示例代码与C 和 C ++兼容。使用普通的旧C来编写Windows程序是完全允许的(并且在某个时间点是标准做法)。
由于C ++强制转换在C中不可用,因此修改示例以利用它们需要维护两份示例代码。由于C代码在C ++中工作,因此将旧样式转换为更容易。