什么时候应该使用 static_cast、dynamic_cast、const_cast 和 reinterpret_cast? [英] When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

查看:29
本文介绍了什么时候应该使用 static_cast、dynamic_cast、const_cast 和 reinterpret_cast?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是正确的用法:

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
  • C-style cast (type)value
  • 函数式转换 type(value)

如何决定在哪些特定情况下使用哪个?

How does one decide which to use in which specific cases?

推荐答案

static_cast 是您应该尝试使用的第一个强制转换.它执行类型之间的隐式转换(例如 intfloat,或指向 void* 的指针),它还可以调用显式转换函数(或隐式函数).在许多情况下,没有必要显式声明 static_cast,但重要的是要注意 T(something) 语法等价于 (T)something 并且应该避免(稍后会详细介绍).然而,T(something, something_else) 是安全的,并且保证调用构造函数.

static_cast is the first cast you should attempt to use. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones). In many cases, explicitly stating static_cast isn't necessary, but it's important to note that the T(something) syntax is equivalent to (T)something and should be avoided (more on that later). A T(something, something_else) is safe, however, and guaranteed to call the constructor.

static_cast 也可以通过继承层次结构进行转换.向上转换(朝向基类)时没有必要,但是向下转换时,只要不通过virtual 继承转换,就可以使用它.但是,它不进行检查,而且将层次结构static_cast 向下转换为实际上不是对象类型的类型是未定义的行为.

static_cast can also cast through inheritance hierarchies. It is unnecessary when casting upwards (towards a base class), but when casting downwards it can be used as long as it doesn't cast through virtual inheritance. It does not do checking, however, and it is undefined behavior to static_cast down a hierarchy to a type that isn't actually the type of the object.

const_cast 可用于删除或添加 const 到变量;没有其他 C++ 类型转换能够删除它(甚至 reinterpret_cast).需要注意的是,只有当原始变量是 const 时,修改以前的 const 值才是未定义的;如果您使用它来取消对未使用 const 声明的内容的引用的 const,则它是安全的.例如,这在基于 const 重载成员函数时很有用.也可以用来给对象添加const,比如调用成员函数重载.

const_cast can be used to remove or add const to a variable; no other C++ cast is capable of removing it (not even reinterpret_cast). It is important to note that modifying a formerly const value is only undefined if the original variable is const; if you use it to take the const off a reference to something that wasn't declared with const, it is safe. This can be useful when overloading member functions based on const, for instance. It can also be used to add const to an object, such as to call a member function overload.

const_castvolatile 上也有类似的作用,但不太常见.

const_cast also works similarly on volatile, though that's less common.

dynamic_cast 专门用于处理多态.您可以将指向任何多态类型的指针或引用转换为任何其他类类型(多态类型至少具有一个声明或继承的虚函数).您不仅可以将它用于向下抛掷 – 您还可以向侧面抛掷甚至向上抛掷另一条链.dynamic_cast 将寻找所需的对象并在可能的情况下返回它.如果不能,则在指针的情况下返回nullptr,在引用的情况下抛出std::bad_cast.

dynamic_cast is exclusively used for handling polymorphism. You can cast a pointer or reference to any polymorphic type to any other class type (a polymorphic type has at least one virtual function, declared or inherited). You can use it for more than just casting downwards – you can cast sideways or even up another chain. The dynamic_cast will seek out the desired object and return it if possible. If it can't, it will return nullptr in the case of a pointer, or throw std::bad_cast in the case of a reference.

dynamic_cast 有一些限制.如果在继承层次结构中有多个相同类型的对象(所谓的可怕的菱形")并且您没有使用 virtual 继承,则它不起作用.它也只能通过公共继承 - 它总是无法通过 protectedprivate 继承.然而,这很少成为问题,因为这种形式的继承很少见.

dynamic_cast has some limitations, though. It doesn't work if there are multiple objects of the same type in the inheritance hierarchy (the so-called 'dreaded diamond') and you aren't using virtual inheritance. It also can only go through public inheritance - it will always fail to travel through protected or private inheritance. This is rarely an issue, however, as such forms of inheritance are rare.

reinterpret_cast 是最危险的转换,应该非常谨慎地使用.它将一种类型直接转换为另一种类型——例如将值从一个指针转换为另一个指针,或者将指针存储在 int 中,或者其他各种令人讨厌的事情.在很大程度上,使用 reinterpret_cast 获得的唯一保证是,通常如果您将结果转换回原始类型,您将获得完全相同的值(但不是 如果中间类型小于原始类型).reinterpret_cast 也无法进行许多转换.它主要用于特别奇怪的转换和位操作,例如将原始数据流转换为实际数据,或将数据存储在指向对齐数据的指针的低位中.

reinterpret_cast is the most dangerous cast, and should be used very sparingly. It turns one type directly into another — such as casting the value from one pointer to another, or storing a pointer in an int, or all sorts of other nasty things. Largely, the only guarantee you get with reinterpret_cast is that normally if you cast the result back to the original type, you will get the exact same value (but not if the intermediate type is smaller than the original type). There are a number of conversions that reinterpret_cast cannot do, too. It's used primarily for particularly weird conversions and bit manipulations, like turning a raw data stream into actual data, or storing data in the low bits of a pointer to aligned data.

C-style castfunction-style cast 是使用 (type)objecttype(object) 分别,并且在功能上是等效的.它们被定义为以下第一个成功的:

C-style cast and function-style cast are casts using (type)object or type(object), respectively, and are functionally equivalent. They are defined as the first of the following which succeeds:

  • const_cast
  • static_cast(尽管忽略访问限制)
  • static_cast(见上文),然后 const_cast
  • reinterpret_cast
  • reinterpret_cast,然后const_cast
  • const_cast
  • static_cast (though ignoring access restrictions)
  • static_cast (see above), then const_cast
  • reinterpret_cast
  • reinterpret_cast, then const_cast

因此在某些情况下它可以用作其他强制转换的替代品,但由于具有转化为 reinterpret_cast 的能力而可能非常危险,并且当显式强制转换为需要,除非您确定 static_cast 会成功或 reinterpret_cast 会失败.即便如此,请考虑更长、更明确的选项.

It can therefore be used as a replacement for other casts in some instances, but can be extremely dangerous because of the ability to devolve into a reinterpret_cast, and the latter should be preferred when explicit casting is needed, unless you are sure static_cast will succeed or reinterpret_cast will fail. Even then, consider the longer, more explicit option.

C 风格的强制转换在执行 static_cast 时也会忽略访问控制,这意味着它们能够执行其他强制转换无法执行的操作.不过,这主要是胡说八道,在我看来,这只是避免 C 风格强制转换的另一个原因.

C-style casts also ignore access control when performing a static_cast, which means that they have the ability to perform an operation that no other cast can. This is mostly a kludge, though, and in my mind is just another reason to avoid C-style casts.

这篇关于什么时候应该使用 static_cast、dynamic_cast、const_cast 和 reinterpret_cast?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆