什么是正确的用法︰

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
  • C 样式强制转换(type)value
  • 函数样式强制转换type(value)

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

2008-12-01 20:11:07

回答:

static_cast是应尝试使用第一个强制转换。是等如 (为float,而int ) 或指向void*,指针类型之间的隐式转换,还可以调用显式转换函数 (或隐式的)。在许多情况下,显式声明static_cast并不是必需的但值得注意的是, T(something)语法等效于(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继承。它也可以只做过公共继承-它将始终无法通过protectedprivate继承旅行。这几乎不是问题,不过,这种形式的继承少见。


reinterpret_cast是最危险的强制转换,并应非常谨慎使用。它将直接插入另一个-例如强制转换到另一个指针的值或将指针存储在一个int或各种其他违规操作的一种类型。很大程度上, reinterpret_cast中获得的唯一保证是,通常情况下如果强制转换回原始类型的结果,您将收到确切的值相同 (但小于原始类型的中间类型时)。有许多的转换该reinterpret_cast不能做,太。它主要用于特别奇怪的转换和位操作,如将原始数据流转变为实际数据,或将数据存储在一个对齐指针的低位。


C 的强制转换是使用(type)objecttype(object)的强制转换。C 样式强制转换被定义为第一个成功的下列情况︰

  • const_cast
  • static_cast(尽管忽略访问限制)
  • static_cast(见上),然后const_cast
  • reinterpret_cast
  • reinterpret_cast,然后const_cast

因此可以使用为其他强制转换在某些情况下,作为替换,但可能会非常危险,因为能够到reinterpret_cast,devolve,后者应优先需要显式强制转换时,除非您确信static_cast会成功或reinterpret_cast将会失败。即使这样,请考虑更长、 更明确的选项。

C 样式强制转换执行static_cast,这意味着它们有能力执行任何其他强制转换可以操作时,也忽略访问控制。不过,这是大多暂且,而且在我看来是避免 C 样式强制转换的只是另一个原因。

我作为第一个选项 dynamic_cast <>,当然只能按上文所述的建议。您可以执行 dynamic_cast <> 时它将检查的类型确实是您所认为。

dynamic_cast 只是多态类型。您只需在要转换为的派生类时使用它。static_cast 的确是第一个选项,除非您特别需要 dynamic_cast 的 functinoality。它不是某些 miraculous 银色项目符号"类型检查广播"一般。

答得好 !一个快速的评语︰ 可能还需要执行 static_cast 以防您有衍生 * 层次结构中向上强制转换和强制转换成基 *,和由于双指针中的引用不自动层次结构中向上强制转换。我是在这样 (坦白地说,不常见) 两分钟以前的情况。;-)

*"其它 c + + 类型转换为能够删除const (即使reinterpret_cast)"...真的吗?怎么样reinterpret_cast<int *>(reinterpret_cast<uintptr_t>(static_cast<int const *>(0)))?

我认为上面缺少重要细节是该 dynamic_cast 运行时性能与静态或 reinterpret_cast。这很重要,如在实时软件。

可用于dynamic_cast转换指针/继承层次结构中的引用。

普通的类型转换中使用static_cast

使用reinterpret_cast的低级别︰ 重新解释的位模式。谨慎使用。

使用const_cast强制转换掉const/volatile避免这种情况除非您不得不使用 const-错误的 API。

const 正确性是 c + + 程序员的最佳工具之一。它可让您进行愚蠢的错误。

(许多理论和概念说明上面被授予)

下面列出了一些实例说明使用static_cast dynamic_castconst_castreinterpret_cast.

(还 referes 这样理解解释︰ http://www.cplusplus.com/doc/tutorial/typecasting/)

static_cast:

OnEventData(void* pData)

{
  ......

  //  pData is a void* pData, 

  //  EventData is a structure e.g. 
  //  typedef struct _EventData {
  //  std::string id;
  //  std:: string remote_id;
  //  } EventData;

  // On Some Situation a void pointer *pData
  // has been static_casted as 
  // EventData* pointer 

  EventData *evtdata = static_cast<EventData*>(pData);
  .....
}

dynamic_cast:

void DebugLog::OnMessage(Message *msg)
{
    static DebugMsgData *debug;
    static XYZMsgData *xyz;

    if(debug = dynamic_cast<DebugMsgData*>(msg->pdata)){
        // debug message
    }
    else if(xyz = dynamic_cast<XYZMsgData*>(msg->pdata)){
        // xyz message
    }
    else/* if( ... )*/{
        // ...
    }
}

const_cast:

// *Passwd declared as a const

const unsigned char *Passwd


// on some situation it require to remove its constness

const_cast<unsigned char*>(Passwd)

reinterpret_cast:

typedef unsigned short uint16;

// Read Bytes returns that 2 bytes got read. 

bool ByteBuffer::ReadUInt16(uint16& val) {
  return ReadBytes(reinterpret_cast<char*>(&val), 2);
}

其他答案的一些理论是很好,但仍令人困惑,看到搞清楚这些示例之后读取其他答案确实使它们所有。这是示例,不我时仍不能确定,但与他们,我现在清楚自己其他的回答意味着什么。

关于最后一个使用的 reinterpret_cast︰ 难道这不与使用相同static_cast<char*>(&val) ?

@LorenzoBelli 当然不是。您试过吗?后者是无效的 c + + 并阻止编译。static_cast只能与定义的转换,通过继承,或到/从可见关系类型之间void *所有其他组件,还有其他的强制转换。对任何reinterpret cast char *允许类型允许读取的表示形式的任何对象-和该关键字很有用,其中唯一的情况下不实施猖獗生成器-/ 未定义的行为。但这不会被视为正常的转换,因此 (通常) 是非常保守的static_cast的不被允许.

Does回答您的问题?

我以前从未使用过reinterpret_cast,并且奇怪是否运行到需要它的用例不可告知的不好的设计。在代码中大量使用dynamic_cast在我工作的基本。使用static_cast的区别就是dynamic_cast作用运行时检查的 (更安全),也可能不会更高 (的开销) 是您想要 (请参阅msdn).

我已经使用了 reintrepret_cast 一个目的 — 获取一个双精度值的位 (大小相同长长基于我的平台)。

"this"不会不回答问题。

reinterpret_cast 如需要使用 COM 对象。CoCreateInstance() 具有输出参数的类型 void * * (最后一个参数),您将指针声明为例如"INetFwPolicy2 * pNetFwPolicy2"。要做到这一点,您需要编写类似于 reinterpret_cast < void * * >(&pNetFwPolicy2)。

虽然此链接可能回答这些问题,最好包括这里的答案的关键部件,并提供链接供参考。只链接的答案可能会变得无效,如果更改了链接的页面。-从审查

其他答案除了到目前为止,这里是 unobvious 示例位置static_cast是不够的因此需要reinterpret_cast假设有一个函数,在输出参数中返回到 (它不共享一个公共基类) 不同类的对象的指针。此类函数的一个实际例子是CoCreateInstance() (请参阅最后一个参数,它实际上是void**)。假设此函数从请求特定类的对象,因此您事先知道 (这通常需要执行 COM 对象) 的指针的类型。在这种情况下,不能将指针与指针到void**使用static_cast︰ 您需要reinterpret_cast<void**>(&yourPointer).

在代码中︰

#include <windows.h>
#include <netfw.h>
.....
INetFwPolicy2* pNetFwPolicy2 = nullptr;
HRESULT hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr,
    CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2),
    //static_cast<void**>(&pNetFwPolicy2) would give a compile error
    reinterpret_cast<void**>(&pNetFwPolicy2) );

但是, static_cast适用于简单指针 (不指向指针的指针),因此上述代码可以重写,以避免reinterpret_cast (额外变量的价格) 在以下方面︰

#include <windows.h>
#include <netfw.h>
.....
INetFwPolicy2* pNetFwPolicy2 = nullptr;
void* tmp = nullptr;
HRESULT hr = CoCreateInstance(__uuidof(NetFwPolicy2), nullptr,
    CLSCTX_INPROC_SERVER, __uuidof(INetFwPolicy2),
    &tmp );
pNetFwPolicy2 = static_cast<INetFwPolicy2*>(tmp);
请输入您的翻译

When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?

确认取消