C++铸造运营商和传统的C铸造运营商

问题描述:

可能重复:
When should static_cast, dynamic_cast and reinterpret_cast be used?C++铸造运营商和传统的C铸造运营商

我已经做了google搜索找到有关的很多:

  1. 为什么要使用C++铸造操作员比传统的C风格铸造操作员?
  2. 何时使用C++转换操作符,一些活生生的实例?

以下是我发现:

  • 传统上的任何C++转换操作符,用于更好的维护您的代码(即),我们不难发现其中的铸造通过在代码只是在寻找这个曾经复杂的符号(reinterpret_cast <)不像C风格的铸造操作符。

现在让我简要说明为什么当每个C++转换操作符

的static_cast的:

为什么使用对C风格的铸造? static_cast用于相关类型之间的转换。

例子:

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:

reinterpret_cast蒙上指向不相关的类型。

例子:

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); 

我的问题是怎么回事,是由C风格的铸造reinterpret_cast不同?我无法找到与传统铸造操作员一起使用它的原因,以及何时使用它?

这使得这些运营商更糟另一个重要的例子是:

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)); 

编写上述代码除去constunsigned要复杂得多在C++铸造?那么,为什么人们使用reinterpret_castconst_caststatic_cast在土产Ç铸造运营商?

我明白约dynamic_cast在多态类的情况下使用;这个运营商也有额外的RTTI费用。

+2

C++转换是C风格演员的限制版本,它试图几乎每一个演员,直到它找到一个作品。当您想要进行某种类型的转换时,应该使用C++样式类型转换,并且如果无法执行该类型的转换,则编译将失败,其中C类型转换用于“只做”转换。 – 2011-12-26 06:20:35

+0

@Mat:从你建议的链接中,我了解了很多。但我在下面有一个疑问,你如何将这种类型的例子映射到C风格的铸造,float a = 13.33; int b = reinterpret_cast (a); ...请让我明白这个 – 2011-12-26 07:28:52

+0

@RishiMehta:我不知道该演员应该扮演什么角色_mean_。你为什么要写这样的“东西”? – Mat 2011-12-26 08:43:56

Google's C++ Style Guide给出了一些动机使用C++风格的转换:

与C类型转换问题在于操作的歧义;有时 您正在进行转换(例如,(int)3.5),有时候您在 正在进行转换(例如(int)"hello"); C++强制避免这种情况。另外 C++强制转换在搜索它们时更加明显。

我喜欢C++类型转换,因为它们使你打算做得非常明确,允许编译器捕捉不正确的用法。

例如,如果您知道您只想对整数进行数值转换,则static_cast仅在数值转换有意义时才会编译。正如您在示例代码中所展示的,C风格转换将执行转换,而不管其有效性。

C++类型转换实际上只是为了更好地记录意图和编译时防止意外使用。

+0

+1的友好链接 – 2011-12-26 06:41:45

+0

是的..该链接是非常值得学习.. 。但是,如果使用C++类型转换的话,你能帮助我吗? – 2011-12-26 06:57:52

+0

我添加了一些到我的答案。这有帮助吗?如果您还有其他问题,我可以给出更确切的例子。 – 2011-12-26 07:12:46

删除const限定符是个坏习惯。您可能最终会写入您不应写入的内存变量或区域。因此,你的问题的一部分无效。

从我的记忆来看,reinterpret_cast和c风格演员几乎是一样的,除非我认为如果你有一个const Thing你不能reinterpret_cast noncost_other_thing(c stye让你删除它们,这可能不是故意的,可能是危险的) 。

我只在自己的项目中使用c铸造,因为我有奢侈的懒惰,有时我不会懒惰。在使用C++时,你'假设'使用C++风格的转换和其他C++特性(ostream而不是文件,没有printf,避免memset和其他不安全的函数等)。但大多数人只是做他们想做的事情(并因此而得到错误)。

通常情况下,如果您知道何时使用dynamic_cast和静态转换,您将会很好。我发现reinterpret_cast不可能,除非我与C接口并需要使用void *。 const_cast ...我从来没有使用过,希望我永远不需要。你应该“总是使用它们。

PS:不相关的说明。我实际上抛出异常并断言(0)未实现的东西。如果我不处理一个参数,并期望它是一个0我会写一个异常或断言检查。当我调试/添加更多的代码,我跑到这些而不是错误和theres绝对没有神秘为什么它发生:)