static_cast

static_cast< new_type >(expression)
  • 相当于传统的C语言里的强制转换
  • 把expression转换为new_type类型
  • 编译时检查,用于非多态的转换,可以转换指针及其他
  • 没有运行时类型检查来保证转换的安全性

用法

  1. 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
    • 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
    • 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
  2. 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
  3. 把空指针转换成目标类型的空指针。
  4. 把任何类型的表达式转换成void类型。
  5. static_cast不能转换掉expression的const、volatile、或者__unaligned属性

例子

char a = 'a';
int b = static_cast<int>(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))
{}//上行转换是安全的

dynamic_cast

dynamic_cast< type* >(e)
//type必须是一个类类型且必须是一个有效的指针
dynamic_cast< type& >(e)
//type必须是一个类类型且必须是一个左值
dynamic_cast< type&& >(e)
//type必须是一个类类型且必须是一个右值

e的类型必须符合以下三个条件中的任何一个:

  • e的类型是目标类型type的公有派生类
  • e的类型是目标type的共有基类
  • e的类型就是目标type的类型。

用法

  • dynamic_cast主要用于类层次间的上行转换下行转换,还可以用于类之间的交叉转换(cross cast)。
  • 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
  • 在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
  • dynamic_cast是唯一无法由旧式语法执行的动作,也是唯一可能耗费重大运行成本的转型动作。

例子

if(Derived *dp = dynamic_cast<Derived *>(bp)){
  //使用dp指向的Derived对象  
}
else{
  //使用bp指向的Base对象  
}

void f(const Base &b){
 try{
   const Derived &d = dynamic_cast<const Base &>(b);  
   //使用b引用的Derived对象
 }
 catch(std::bad_cast){
   //处理类型转换失败的情况
 }
}