C++铸造操作员和传统的C型铸造操作员

C++ Casting Operators and traditional C casting operators

本文关键字:操作员 C++ 传统      更新时间:2023-10-16

可能的重复项:
何时应使用static_cast、dynamic_cast和reinterpret_cast?

我做了很多谷歌搜索来查找:

  1. 为什么使用C++铸造运算符而不是传统的C型铸造操作器?
  2. 何时使用C++铸造运算符,一些活生生的例子?

以下是我的发现:

  • 传统上,任何C++转换运算符都用于更好地维护代码(即(与 C 样式转换运算符不同,我们可以通过搜索此复杂符号 (reinterpret_cast<( 轻松找到代码中使用转换的位置。

现在让我简要说明每个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);

我的问题是reinterpret_cast与 C 样式铸造有何不同?我找不到为什么在传统的铸造操作员上使用它以及何时使用它?

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

   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而不是传统的C铸造操作员呢?

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

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

C 转换的问题在于操作的歧义;有时 您正在进行转换(例如,(int)3.5(,有时您是 做石膏(例如,(int)"hello"(;C++演员表避免了这一点。此外 C++ 在搜索时,它们更明显。

我喜欢C++强制转换,因为它们使您打算执行的操作非常明确,允许编译器捕获不正确的用法。

例如,如果您知道您只打算将数字转换为整数,则static_cast仅在该数字转换有意义时进行编译。如示例代码所示,无论有效性如何,C 样式强制转换都将执行强制转换。

C++强制转换实际上只是为了更好地记录意图,并针对意外使用的编译时保护。

删除 const 限定符是一种不好的做法。 您最终可能会写入不应该写入的内存变量或区域。 因此,这使您问题的这一部分无效。

根据

我的记忆,reinterpret_cast与 c 样式强制转换几乎相同,除了我认为如果你有一个 const 你不能reinterpret_cast的东西来noncost_other_thing(c stye 让你删除它们,这可能不是故意的,可能是危险的(。

我只在自己的项目中使用 c casting,因为我有懒惰的奢侈,有时我不会偷懒。在使用C++时,您"应该"使用C++样式转换和其他C++功能(ostream而不是file,没有printfs,避免memset和其他不安全的功能等(。但大多数人只是为所欲为(并因此而获得错误(。

通常,如果您知道何时使用dynamic_cast和静态转换,您就会没事的。我发现reinterpret_cast不太可能,除非我与 C 接口并且需要使用 void*。const_cast...我实际上从不使用,希望我永远不需要。而且您"应该"始终使用它们。

PS:不相关的注释。我实际上在未实现的事情上抛出异常和断言(0(。如果我不处理参数并期望它是 0,我会写一个异常或断言来检查它。当我调试/添加更多代码时,我会遇到这些而不是错误,并且绝对没有关于为什么会发生:)