1

Win32 API 的某个教程使用这一行将lParam参数从WM_CREATE主窗口过程中的消息转换为CREATESTRUCT*

reinterpret_cast<CREATESTRUCT*>(lParam)  // Method 1

我在其他地方读过reinterpret_cast很危险的文章,会导致未定义的行为、闪电等等。


我使用了编译器不会抱怨的更传统的演员表:

(CREATESTRUCT*) lParam // Method 2

本教程的作者这样做有什么原因吗?

而且,我确定有比我更好的方法吗?

4

2 回答 2

4

在这种特殊情况下,这两种结构是等价的。没有未定义的行为——C++ 标准保证将指针重新解释转换为足够宽的整数并返回会产生相同的指针。

您可以放心地假设 WindowslParam从原始指针创建值,就好像通过reinterpret_cast.

于 2012-10-31T09:00:37.520 回答
1

“(CREATESTRUCT*) lParam”形式称为 c 样式转换。当使用它时,编译器将尝试所有可能的方法将表达式(lParam - 这里)转换为类型(CREATESTRUCT* - 这里)。

让我解释所有可能的铸造方式,

  1. 从“const/volatile T”转换为 T - 在 C++ 中,程序员使用const_cast选择这种方式
  2. 从“T”转换为“R”,其中 T 和 R 相关。例如,像 int/char、Car/Vehicle 等 - 在 C++ 中,程序员使用static_cast选择这种转换方式。
  3. 从“T”转换为“R”,其中 T 和 R 相关,以及运行时检查。例如 T = Vehicle 和 R = Car,从 T 类型对象到 R 类型对象的转换是静态有效的,但实际上(在运行时)编译器(通过隐藏代码)必须检查被类型转换的对象是否确实是 Car 或Car的衍生产品。- 在 C++ 中,程序员使用dynamic_cast选择这种转换方式。
  4. 从“U”转换为“V”,其中 U 和 V 不相关。- 在 C++ 中,程序员使用reinterpret_cast选择这种转换方式。

如果程序员在 C++ 中使用 c 样式转换,他是在告诉编译器尝试所有可能的方法来将表达式转换/感知为/作为特定类型。

c-style cast 危险的唯一原因是程序员的真正意图没有正确地传达给编译器和阅读代码的其他程序员。有时程序员可能只意味着 static_cast 而不是 reinterpret_cast 但使用 c 风格的强制转换会在运行时导致错误,这可能在编译时被捕获。因为如果程序员在不相关的类型上使用 static_cast 会发生编译器错误。

并且用户定义的强制转换运算符对某些行为的影响更大(尤其是 static_cast),但不会改变基本原理。

于 2012-10-31T09:50:32.640 回答