C++ 里的 cast-name (expression) 强制类型转换可以用 C 的方式表示,但用 cast-name (expression) 使类型转换具有可视性,这样一来程序员可清楚地辨别代码中每个显式的强制转换潜在的风险级别。
强制类型转换的分类:
//
指针的强制类型转换
if (Derived * pDerived = dynamic_cast < Derived *> (pBase))
... {
// successd
} else ... {
// failure
}
// 引用的强制类型转换
try ... {
const Derived& derived = dynamic_cast<Derived&>(base);
} catch (bad_cast) ... {
// handle the fact that the cast failed
}
if (Derived * pDerived = dynamic_cast < Derived *> (pBase))
... {
// successd
} else ... {
// failure
}
// 引用的强制类型转换
try ... {
const Derived& derived = dynamic_cast<Derived&>(base);
} catch (bad_cast) ... {
// handle the fact that the cast failed
}
注意: dynamic_cast 只为带有一个或多个虚函数的类返回动态类型信息,对于其他类型,返回静态(即编译时)类型的信息。
注: 从基类获得派生类行为最好的方法是通过虚函数,只有在不可能使用虚函数的情况才使用 RTTI,因为这种机制比使用虚函数更容易出错:程序员必须知道应该将对象强制转换为哪种类型,并且检查转换是否成功!
-
const_cast
转换掉表达式的 const 性质。比如:
const char * pcStr;
char * pStr = const_cast < char *> (pcStr);
static_cast
编译器隐式执行的任何类型转换都可以由 static_cast 显式完成:
double d = 100.0 ;
char c = static_cast < char > (d);
void * p;
double * pD = static_cast < double *> (p);reinterpret_cast
为操作数的位模式提供较低层次的重新解释:
int * pI;
char * pC = reinterpret_cast < char *> (pI);注意: reinterpret_cast 本质上依赖于机器。为了安全地使用它,要求程序员完全理解所设计的数据类型,以及编译器实现强制转换的细节。
建议: 避免使用强制类型转换
强制类型转换关闭或挂起了正常的类型检查。强烈建议避免使用它!特别是对于 reinterpret_cast。每次使用强制类型转换时,程序员应该仔细考虑是否还有其他不同的方法可以达到同一目的。如果非要强制转换不可,则应限制强制转换值的作用域,并且记录所有假定涉及的类型,这样能减少错误发生的机会。