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

在C++中完全避免C风格的转换是可能的吗?

  •  6
  • sourcenouveau  · 技术社区  · 14 年前

    我不相信在编写C++时完全避免C风格的强制转换。我很惊讶 find out 我需要使用C样式转换来避免编译器截断警告:

    short value_a = 0xF00D;                     // Truncation warning in VS2008
    short value_b = static_cast<short>(0xF00D); // Truncation warning in VS2008
    short value_c = (short)0xF00D;              // No warning!
    

    有其他场景,没有C风格的替代C风格的演员吗?

    6 回复  |  直到 14 年前
        1
  •  3
  •   Jens Gustedt    14 年前

    你只是想混淆你的代码,就这么简单。编译器告诉你的是完全正确的。

    如果您对分配的值应该是什么有一个精确的概念,那么就使用它。我猜你有一些毫无根据的假设 short 16位宽,目标机的符号表示是2的补码。如果是这样,将-4083赋给变量。如果只需要将变量作为位向量,请使用无符号类型。

    就C而言,标准只是简单地说明了从一种整数类型到另一种整数类型的转换:

    否则,将对新类型进行签名并 该值不能在其中表示; 结果要么是 定义的实现或 实现定义的信号是 提高。

    我想C++的观点与这方面没有多大区别。其他的答案提到了C++中的边界情况,你需要一个“C”风格的转换来否决C++给你的所有类型的检查。感觉到对它们的需要是坏设计的一个标志。

    你举的例子肯定不是我能找到任何有效情况的。

        2
  •  12
  •   GManNickG    14 年前

    在C++中,C++风格的铸件是根据C++风格的铸件来定义的。所以对于每一个你可以做C风格的演员,都有一个匹配的C++风格的演员阵容(几乎)。

    “几乎”是C样式的强制转换忽略了基类的可访问性。也就是说,不存在等价的C++风格的铸件如下:

    struct foo {};
    struct bar : private foo {};
    
    bar b;
    foo* f = (foo*)&b; // only way this can be done in a well-defined manner
    

    所以,不,严格来说,完全抛弃C型演员是不可能的。但是,(C++)风格转换的组合的数量不足以计数。


    以上是“语言答案”。您所经历的与C样式转换与C++版本无关,而只是编译器实现。警告绝对是特定于实现的,与C++无关。

    所以不要误用你的发现 在这种特定的情况下,在这个特定的编译器上 做总结 关于C++的一般性 .

        3
  •  2
  •   Community CDub    8 年前

    是的,这是完全可能的。

    我从不使用C型铸造。我可以编写数十万行代码,而不必使用 reinterpret_cast C++关闭了C样式的表兄弟。我唯一需要使用的时间 重新解释铸模 是在进行套接字编程时——在大局中是一个相当狭窄的领域。

    不要 需要 也可以使用C型铸造。在你 other post 你说

    我可以用负值,

    short my_value = -4083;
    

    但在我的代码中,使用十六进制更容易理解。

    所以在这种情况下,你不必使用石膏。你选择了。

        4
  •  0
  •   sbi    14 年前

    我很惊讶地发现我需要使用C样式的强制转换来避免编译器截断警告。

    我是从另一个角度看的:你使用C样式的演员表 防止编译器警告您 我认为这是C型铸造的一个严重缺点。

    如果你觉得你知道自己在做什么,那么就用一种编译器特有的方式关闭这个案例的编译器。例如,对于VC,使用

    #pragma warning(push, disable: XXXX)
    // code goes here
    #pragma warning(pop)
    
        5
  •  0
  •   tyree731    14 年前

    有4种C++风格的铸件,StistaCube,RealType铸件,StistaCype和DyrimCype铸件。它们的工作原理如下:

    // const_cast casts away constness or adds it
    const int const_integer = 5;
    const_cast<int>(const_integer) = 3;
    
    // static_cast will perform standards defined casts and will 
    // cast up or down a c++ inheritance hierarchy without checking the result of the cast
    struct b {};
    struct a : public b {};
    struct c {};
    double value = static_cast<double>(0.0f);
    b* b_value = new b;
    a* a_value = static_cast<a*>(b_value);
    
    // dynamic_cast will perform any cast that static_cast will, but will check to see
    // if the cast makes sense. If the values are not pointers, this cast can throw
    b* value_b = new b;
    a* value_a = new a;
    b* new_b = dynamic_cast<b*>(value_a); // will return NULL
    a* new_a = dynamic_cast<a*>(value_b); // will not return NULL    
    
    // reinterpret_cast will change any type to any other type, as long as the constness of the types is the same.
    // the behavior of this cast is implementation specific.
    double* a = new double;
    *a = 0.0f;
    int *b = reinterpret_cast<int*>(a);
    

    C++中的C风格铸件只是试图按特定顺序执行这些铸件,直到其中一个工作。顺序如下:

    • 连续铸造
    • 静止石膏
    • 静态类型转换后是常量类型转换
    • 重新解释,或
    • 一个重新解释的剧组,接着是一个警察剧组。

    因此,简而言之,您可以在C++中做任何C风格的转换,因为C++中的C风格的转换只是C++样式转换的一些安排。了解了?

        6
  •  -3
  •   Diego Sevilla    14 年前

    在这些情况下,您可以使用 reinterpret_cast . 它是为了取代未经检查的C型铸造。这里的典型注释:这是未选中的强制转换,应尽可能避免使用其他可用的: const_cast , dynamic_cast 等。