C ++
什么是正确的用途:
static_cast
dynamic_cast
const_cast
reinterpret_cast
(type)value
type(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_cast
static_cast
(尽管忽略访问限制) static_cast
(见上面),然后是const_cast
reinterpret_cast
reinterpret_cast
,然后是const_cast
因此,在某些情况下,它可以用作其他演员的替代品,但由于能够分解为reinterpret_cast
,因此可能非常危险;如果需要显式演员,则应优先选择后者,除非您确定static_cast
会成功或reinterpret_cast
将失败。 即便如此,考虑更长,更明确的选择。
C风格转换在执行static_cast
时也会忽略访问控制,这意味着它们可以执行其他类型转换无法执行的操作。 不过,这主要是一个混乱,在我看来,这是避免C型演员阵营的另一个原因。
使用dynamic_cast
在继承层次结构内转换指针/引用。
使用static_cast
进行普通类型转换。
使用reinterpret_cast
进行位模式的低级重新解释。 谨慎使用。
使用const_cast
来转换const/volatile
。 避免这种情况,除非你使用常量不正确的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);
}
链接地址: http://www.djcxy.com/p/749.html
上一篇: c++