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++
