有什么用途:
static_castdynamic_castconst_castreinterpret_cast- C风格演员
(type)value - 功能式演员
type(value)
如何确定在哪些特定情况下使用哪个?
有什么用途:
static_castdynamic_castconst_castreinterpret_cast(type)valuetype(value)如何确定在哪些特定情况下使用哪个?
static_cast 是你应该尝试使用的第一个演员。它执行类型之间的隐式转换(例如 int 至 float或指向 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 遗产。它也只能通过公共继承 - 它总是无法通过 protected 要么 private 遗产。然而,这很少是一个问题,因为这种形式的遗传很少见。
reinterpret_cast 是最危险的演员,应该非常谨慎地使用。它将一种类型直接转换为另一种类型 - 例如将值从一个指针转换为另一个指针,或将指针存储在一个指针中 int或者各种其他讨厌的东西。很大程度上,这是你唯一的保证 reinterpret_cast 通常,如果您将结果转换回原始类型,您将获得完全相同的值(但是 不 如果中间类型小于原始类型)。有很多转换 reinterpret_cast 也做不到。它主要用于特别奇怪的转换和位操作,例如将原始数据流转换为实际数据,或将数据存储在对齐指针的低位中。
C风格演员 和 功能式演员 是演员使用 (type)object 要么 type(object), 分别。 C样式转换定义为以下第一个成功:
const_caststatic_cast (虽然忽略了访问限制)static_cast (见上文),然后 const_castreinterpret_castreinterpret_cast, 然后 const_cast因此,它可以在某些情况下用作其他演员阵容的替代品,但由于能够转换成其他演员阵容,因此可能非常危险。 reinterpret_cast除非你确定,否则当需要显式铸造时,后者应该是首选 static_cast 会成功还是 reinterpret_cast 将失败。即使这样,也要考虑更长,更明确的选择。
执行a时,C风格的强制转换也会忽略访问控制 static_cast,这意味着他们有能力执行其他演员无法进行的操作。不过,这主要是一个kludge,在我看来,这是避免C风格演员阵容的另一个原因。
使用 dynamic_cast 用于转换继承层次结构中的指针/引用。
使用 static_cast 用于普通类型的转换。
使用 reinterpret_cast 用于低级重新解释位模式。使用时要格外小心。
使用 const_cast 扔掉 const/volatile。除非你使用const不正确的API,否则请避免这种情况。
(上面已经给出了很多理论和概念上的解释)
以下是一些 实际例子 我用的时候 的static_cast, 的dynamic_cast, const_cast会, reinterpret_cast的。
(也可以参考这一点来理解解释: 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);
}
如果你对内部有点了解,它可能会有所帮助......
的static_cast
A* 至 B* 如果A和B在继承层次结构(或void)中,则总是成功,否则会出现编译错误。A& 至 B&。的dynamic_cast
(Base*) 至 (Derived*)如果指针实际上不是派生类型,则可能会失败。A* 至 B*,如果强制转换无效,那么dynamic_cast将返回nullptr。A& 至 B& 如果强制转换无效,则dynamic_cast将抛出bad_cast异常。const_cast会
set<T> 它仅将其元素作为const返回,以确保您不更改其键。但是,如果您的目的是修改对象的非关键成员,那么它应该没问题。您可以使用const_cast删除constness。T& foo() 以及 const T& foo()。为避免代码重复,可以应用const_cast从一个函数返回另一个函数的值。reinterpret_cast的
是否 这个 回答你的问题?
我从来没用过 reinterpret_cast并且想知道是否遇到需要它的情况并不是一种糟糕的设计气味。在我的代码库中工作 dynamic_cast 经常使用。与...的区别 static_cast 是那个 dynamic_cast 做运行时检查可能(更安全)或不可能(更多开销)是你想要的(见 MSDN)。
除了到目前为止的其他答案,这里是不明显的例子 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);