static_cast VS dynamic_cast

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){
     
   //处理类型转换失败的情况
 }
}

3. 尽量少使用转型操作,尤其是dynamic_cast,耗时较高,会导致性能的下降,尽量使用其他方法替代。

你可能感兴趣的:(C++和C语言)