C ++ Casting Operators和传统的C cast操作符

C++ Casting Operators and traditional C casting operators

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
When should static_cast, dynamic_cast and reinterpret_cast be used?

我做了很多谷歌搜索来发现:

  • 为什么使用C++铸造操作符优于传统的C型铸造操作符?
  • 什么时候使用C++的浇铸操作符,一些活的例子?
  • 以下是我发现的:

    • 传统上,任何C++铸造操作符都被用来更好地维护代码(IE)。我们可以很容易地找到C铸造在代码中使用的地方,只是搜索这个复杂的符号(RealTytCase<)不同于C样式的铸造操作符。

    现在让我简要说明每个C++操作符的原因和时间。

    静态铸造:

    为什么在C型铸造上使用它?static_cast用于在相关类型之间进行转换。

    实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
     Class A {};
     Class B {};

     A* a = new A();
     B* b = static_cast<B*>(a); // Compiler error
     B* b1 = (A*)a;  // Works fine
     float f;
     int addr = (int)(&f); // Works fine
     int addr = static_cast<int>(&f);  // Compiler error

    但我想知道一个真正的用例,什么时候使用上面的代码?

    重新解释铸造:

    reinterpret_cast将指针强制转换为不相关的类型。

    实例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     Class A {};
     Class B {};

     A* a = new A();
     B* b = reinterpret_cast<B*>(a); // Works fine
     B* b1 = (A*)a;  // Works fine
     float f;
     int addr = (int)(&f); // Works fine
     int addr = reinterpret_cast<int>(&f);  // Works fine


     int ai = 10;
     float af = 13.33;
     // Would depend on how floating point is stored in machine
     // int& since reinterpret_cast expects either the type or operand to be pointer or reference
     int ki = reinterpret_cast<int&>(af); // ki would not be 13
     int kitemp = (int)af; // kitemp would be 13

     // The same reinterpret_cast behaviour can be achieved using this,
     int* in = (int*)(af);
     cout << (*in);

    我的问题是,reinterpret_cast与C型铸造还有什么不同?我找不到为什么要用它来代替传统的铸造操作,也找不到什么时候用它?

    另一个使这些运算符更糟的重要示例是:

    1
    2
    3
    4
    5
       const unsigned int * p;
       (int*)p; // Would remove unsigned and const at one shot
       // Using C++ casting operators
       // Const_cast expects a pointer or a reference
       reinterpret_cast<int*>(const_cast<unsigned int* >(p));

    编写上面的代码来删除EDCOX1,3,EDCOX1,4,在C++中复杂得多吗?那么,为什么人们使用reinterpret_castconst_caststatic_cast的铸造操作员超过传统的C型铸造操作员?

    我确实了解在多态类的情况下使用的dynamic_cast;同样,这个操作符也有一个额外的rtti成本。


    谷歌的C++风格指南给出了使用C++样式转换的一些动机:

    The problem with C casts is the ambiguity of the operation; sometimes
    you are doing a conversion (e.g.,(int)3.5) and sometimes you are
    doing a cast (e.g., (int)"hello"); C++ casts avoid this. Additionally
    C++ casts are more visible when searching for them.

    我喜欢C++的转换,因为它们使你想要做的非常明确,允许编译器捕获错误的用法。

    例如,如果您知道您只打算将数字转换为整数,那么只有在数字转换有意义时,static_cast才会编译。正如您在示例代码中所显示的那样,无论有效性如何,C样式的强制转换都将执行强制转换。

    C++的转换实际上是为了更好地记录意图,以及编译时保护以防止意外使用。


    在我的记忆中,重新解释投射和C样式投射几乎是一样的,除非我认为如果你有一个常量,你不能重新解释投射到非主体的其他事物(C样式允许你移除它们,这可能不是有意的,也可能是危险的)。

    我只在自己的项目中使用C角色扮演,因为我有懒惰的奢侈,有时我也不懒惰。在使用C++时,你可以假设使用C++风格的铸造和其他C++特性(OFSUAM,而不是文件,没有打印输出,避免MeMSET和其他不安全的功能等)。但大多数人只是做他们想做的事(并因此而得到错误)。

    通常,如果您知道何时使用动态强制转换和静态强制转换,就可以了。我发现重新解释不太可能,除非我与C接口,需要与void*一起工作。康斯特卡斯特…实际上我从不使用,希望我永远不需要。你应该经常使用它们。

    附:无关注释。实际上,我对未实现的事物抛出异常并断言(0)。如果我不处理一个参数并期望它是0,我将编写一个异常或断言来检查它。当我调试/添加更多的代码时,我会遇到这些代码而不是错误,而且完全不知道为什么会发生这种情况。)


    删除const限定符是一种糟糕的做法。您可能最终会写入一个不应该写入的变量或内存区域。所以这部分问题就无效了。