1. static_cast
1.1
- 使用方法
static_cast<new_type>(expression)
new_type
为目标数据类型,expression
为原始数据变量或者表达式。该操作相当于c语言的强制转换,将expression的类型强制转换为new_type类型,用来强迫隐式转换如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性.。它主要有以下几种用法:
① 用于类层次结构中基类和派生类之间指针引用和转换:
进行上行转换(把派生类指针或引用转为基类)是安全的;
进行下行转换时(基类转派生类),由于没有动态检查,所以是不安全的;
② 基本数据类型之间的转换,如int ->char; int->enum
③ 空指针转换为目标类型空指针
④ 把任何类型的表达式转为void类型
1.2
char a = 'a';
int b = static_cast<char>(a);//正确,将char型数据转换成int型数据
double *c = new double;
void *d = static_cast<void*>(c);//正确,将double指针转换成void指针
int e = 10;
const int f = static_cast<const int>(e);//正确,将int型数据转换成const int型数据
const int g = 20;
int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性
class Base
{};
class Derived : public Base
{}
Base* pB = new Base();
if(Derived* pD = static_cast<Derived*>(pB))
{}//下行转换是不安全的(坚决抵制这种方法)
Derived* pD = new Derived();
if(Base* pB = static_cast<Base*>(pD))
{}//上行转换是安全的
2. dynamic_cast详解
2.1
dynamic_cast<type*>(e)//type必须是一个类类型且为有效的指针
dynamic_cast<type&>(e)//type为一个左值
dynamic_cast(type&&)(e)//type为一个右值
e
的类型必须符合以下三个条件之一
(1)e的类型是目标类型type的公有派生类;
(2)e的类型是目标type的公有基类
(3)e为目标type的类型
2.2
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换(cross cast)。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。dynamic_cast是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。
(1)指针类型
举例,Base为包含至少一个虚函数的基类,Derived是Base的共有派生类,如果有一个指向Base的指针bp,我们可以在运行时将它转换成指向Derived的指针,代码如下:
if(Derived *dp = dynamic_cast<Derived *>(bp)){
//使用dp指向的Derived对象
}
else{
//使用bp指向的Base对象
}
(2)引用类型
因为不存在所谓空引用,所以引用类型的dynamic_cast转换与指针类型不同,在引用转换失败时,会抛出std::bad_cast异常,该异常定义在头文件typeinfo中。
void f(const Base &b){
try{
const Derived &d = dynamic_cast<const Base &>(b);
//使用b引用的Derived对象
}
catch(std::bad_cast){
//处理类型转换失败的情况
}
}