代码之家  ›  专栏  ›  技术社区  ›  Marlon

关于C++的困惑

  •  12
  • Marlon  · 技术社区  · 16 年前

    我一直在阅读关于C++的很多内容,我开始感到困惑,因为我一直使用C风格的铸件。

    我已经读到C++中应该避免C样式的铸造,并且RealTytPipe非常非常危险,当有其他选择时,不应该使用它。与不使用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;
          }
       }
    
       ...
    }
    

    如果这不正常,那么如何仅使用静态、动态和/或常量转换将lparam值转换为指针?

    另外:如果reinterpret-cast不可移植,我如何将其重写为可移植(为了更好的实践)

    5 回复  |  直到 16 年前
        1
  •  8
  •   MikeP    16 年前

    如果您知道指针最初是目标类型,那么使用reinterpret-cast是可以接受的。任何其他用途都利用了依赖于实现的行为,尽管在许多情况下这是必要和有用的,例如将指向结构的指针强制转换为指向字节的指针,以便将其序列化。

    它被认为是危险的,因为它在编译时或运行时都不进行检查。如果你犯了一个错误,它会崩溃并严重烧坏,而且很难调试。您本质上是在告诉编译器“我比您更清楚这实际上是什么,所以只需编译代码,让我担心后果。”

        2
  •  5
  •   Frank Krueger    16 年前

    您在msdn上看到它的原因是因为win32 api是 C 但是人们坚持在 C++ .

    当您编写与其他库接口的代码时,reinterpret cast很好。应该避免 在你自己的应用程序中 .

        3
  •  3
  •   GBegen    16 年前

    这是一个用C++编写的Windows平台SDK,一个C API的例子。window过程只有wparam和lparam参数,如果需要通过window消息向结构传递指针,则必须强制转换。在我看来,这是一种完全可以接受的重新解释的用法。您不能避免强制转换,因为您正在编写的SDK(不是代码)不是为C++设计的,更不用说类型安全性,并且需要通过铸造来提供具有C绑定的泛型参数类型。

    这是一个让您知道需要小心的标志,但无论如何都不能避免。

    另一方面,如果您控制了代码的两边、API和使用者,那么最好让一个类型安全且不要求使用者执行强制转换来正确使用它的API。

        4
  •  2
  •   Alan    16 年前

    不要忽视MSDN,但MSDN并不是进行正确C++编码的最佳场所。

    使用reinterpret_cast的一个原因是当您从不透明数据类型转换到/转换时。重新解释代码并不是“危险的”,只是很容易出错并导致代码出现问题,所以应该避免这种情况。

    C++风格转换的首选原因是StasyType是类型化的,并且所有的铸造时间更容易搜索。

    程序员[错误地]经常使用强制转换来“取消编译器警告”,例如从无符号整数转换为有符号整数,或从32位整数转换为8位整数。

        5
  •  2
  •   Nikolai Fetissov    16 年前

    基本上 reinterpret_cast C结构和基本类型的“安全”吗(如铸造等明显错误) int 指向一个指针并返回,它在ILP32体系结构上工作,但在LP64 One上中断。)C结构中没有任何内容,除了您没有声明的可能的对齐填充之外。

    重新解释铸模 因为编译器将数据项插入到类中,所以C++的多态类型是不安全的。 指向虚拟表的指针 指向虚拟基类的指针 . 其他C++编译器注意调整这些,例如,向下铸造,从指针到基类到派生类的指针, 重新解释铸模 而C型石膏则不然。