C++铸造操作员和传统的C型铸造操作员
C++ Casting Operators and traditional C casting operators
可能的重复项:
何时应使用static_cast、dynamic_cast和reinterpret_cast?
我做了很多谷歌搜索来查找:
- 为什么使用C++铸造运算符而不是传统的C型铸造操作器?
- 何时使用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));
编写上面的代码来删除const
和unsigned
在C++铸造中要复杂得多?那么为什么人们使用reinterpret_cast
、const_cast
或static_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,我会写一个异常或断言来检查它。当我调试/添加更多代码时,我会遇到这些而不是错误,并且绝对没有关于为什么会发生:)
- <<操作员在下面的行中工作
- C++ 与操作员不匹配<<
- 操作员C++的模棱两可的过载
- C++中>>操作员过载时出现问题?
- NaN 上的宇宙飞船操作员
- 比根<操作员
- SFINAE不能防止模棱两可的操作员过载吗?
- 什么是现实中的"endl"(或任何输出操纵器)?它是如何实现的,它如何与操作员<<一起工
- 为什么"delete"操作员给我访问权限冲突
- 为什么使操作员成为新的专用会打破 std::shared_ptr?
- 在这种情况下是私有的吗?试图使操作员<<过载
- C++操作员过载>>
- 是否有 C++20 浮点数的包装器,使我能够默认宇宙飞船操作员?
- 与异常处理程序中的操作员<<不匹配
- 复印作业操作员说明
- 友谊和操作员+=重载
- >操作员在比较两个C++容器时会怎么做?
- 与操作员比较两个计时时间点
- C++操作员订单评估
- 如何强制新操作员根据我的需要解释语句