问题

以下各项的正确用途:

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
  • C-style cast (type)value
  • Function-style cast type(value)

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



解决方法

static_cast 是您应该尝试使用的第一个投射.它做类似类型之间的隐式转换(例如 int float 或指向 void * ),也可以调用显式转换函数(或隐式的).在许多情况下,明确说明 static_cast 是没有必要的,但重要的是要注意 T(something)语法相当于代码>,应该避免(以后会更多).一个 T(something,something_else)是安全的,但是,并保证调用构造函数.

static_cast 也可以通过继承层次结构进行转换.当向上投射(向基类)时是不必要的,但是向下投射时,只要它不通过 virtual 继承来投射就可以使用.它不做检查,然而,它是未定义的行为 static_cast 下一个层次结构类型,实际上不是对象的类型.


const_cast 可用于删除或添加 const 没有其他C ++转换能够删除它(甚至 reinterpret_cast ).重要的是注意,如果原始变量是 const ,则修改以前的 const 值是未定义的;如果你使用它来取代未被 const 声明的 const 引用,那么它是安全的.例如,当重载基于 const 的成员函数时,这可能很有用.它还可以用于向对象添加 const ,例如调用成员函数重载.

const_cast volatile 上也有同样的效果,虽然不常见.


dynamic_cast 几乎专用于处理多态性.您可以将任何多态类型的指针或引用转换为任何其他类类型(多形类型至少有一个虚函数,声明或继承).你可以使用它不仅仅是向下投 - 你可以横向或甚至另一个链. dynamic_cast 会找出所需的对象,并在可能的情况下返回它.如果不能,在指针的情况下,它将返回 nullptr ,或者在引用的情况下引发 std :: bad_cast .

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


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


使用(type)对象类型(对象)投射 代码>. C风格的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 会失败.即使那样,考虑更长,更明确的选项.

C风格的Cast在执行 static_cast 时也会忽略访问控制,这意味着它们能够执行没有其他转换的操作.这大部分是一个kludge,虽然,在我看来,只是另一个原因,以避免C风格的演员.




相关问题推荐