是否有可能在C ++中完全避免使用C风格的强制转换?

我不相信在编写C ++时可以完全避免使用C风格的强制转换。 我惊讶地发现我需要使用C风格的转换来避免编译器截断警告:

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

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

您只是试图模糊您的代码,就这么简单。 并且编译器完全正确地告诉你。

如果您准确了解指定的值应该是什么,请使用它。 我的猜测是你有一些毫无根据的假设,即16比特宽的short ,并且目标机器的符号表示是两个补码。 如果是这样,请为变量分配-4083。 如果您只需要将变量作为位向量,请使用无符号类型。

就C而言,标准只是说从一个整数类型转换到另一个整数类型:

否则,新类型将被签名,并且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号。

我想C ++在这方面的观点并没有太大的不同。 其他答案提到边界情况,在C ++中你需要一个`C’风格的演员来否决C ++给你的所有类型检查。 感觉需要它们表明设计糟糕。

你作为一个例子给出的案例肯定不是我会找到任何有效情况的案例。

在C ++中,C风格的强制转换是根据C ++风格的强制转换定义的(第5.4节)。 因此,对于每个演员你可以做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 ++的内容

是的,这是完全可能的。

我从不使用C风格的演员阵容。 我可以编写成千上万行代码,而不必回复使用reinterpret_cast ,C ++关闭Cousin演员。 我必须使用reinterpret_cast的唯一一次是在进行套接字编程时 – 一个相当狭窄的域,在大图中。

也不需要使用C风格的演员表。 在你的另一篇文章中 ,你说

我可以使用负值,

 short my_value = -4083; 

但在我的代码中,使用hex更容易理解。

所以在这种情况下你不必使用演员表。 你选择了。

我很惊讶地发现我需要使用C风格的转换来避免编译器截断警告

我反过来看:你使用C风格的强制转换来阻止编译器警告你 ,我认为这是C风格强制转换的一个严重缺点。

如果您觉得自己知道自己在做什么,那么请使用特定于编译器的方式关闭这个案例的编译器。 例如,对于VC使用类似的东西

 #pragma warning(push, disable: XXXX) // code goes here #pragma warning(pop) 

有4个c ++样式转换,const_cast,reinterpret_cast,static_cast和dynamic_cast。 他们的工作如下:

 // const_cast casts away constness or adds it const int const_integer = 5; const_cast(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(0.0f); b* b_value = new b; a* a_value = static_cast(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(value_a); // will return NULL a* new_a = dynamic_cast(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(a); 

c ++中的c样式转换只是尝试按特定顺序执行这些转换,直到其中一个转换为止。 该命令如下:

  • 一个const_cast
  • 一个static_cast
  • static_cast后跟const_cast
  • reinterpret_cast,或
  • 一个reinterpret_cast,然后是一个const_cast。

所以,简而言之,你可以在c ++中进行任何c风格的转换,因为c ++中的c风格转换只是c ++风格转换的一些安排。 得到它?

在这些情况下,您可以使用reinterpret_cast 。 这是为了取代未经检查的C风格演员阵容。 这里的典型注释:这是未经检查的强制转换,应该尽可能避免使用其他可用的: const_castdynamic_cast等。