C++的四种cast转换

C++的四种cast转换:static_cast、dynamic_cast、const_cast、reinterpret_cast

文章转载:https://www.cnblogs.com/chenyangchun/p/6795923.html

注:
上行(向上)转换:指的是子类向基类的转换
下行(向下)转换:指的是基类向子类的转换

  1. const_cast

    用于将const变量转为非const

    const_cast,用于修改类型的const或volatile属性。
    该运算符用来修改类型的const(唯一有此能力的C+±style转型操作符)或volatile属性。除了const 或volatile修饰之外, new_type和expression的类型是一样的。
    ①常量指针被转化成非常量的指针,并且仍然指向原来的对象;
    ②常量引用被转换成非常量的引用,并且仍然指向原来的对象;
    ③const_cast一般用于修改底指针。如const char *p形式。
    举例转换如下:

    const int g = 20;
    int *h = const_cast<int*>(&g);//去掉const常量const属性
    
    const int g = 20;
    int &h = const_cast<int &>(g);//去掉const引用const属性
    
    const char *g = "hello";
    char *h = const_cast<char *>(g);//去掉const指针const属性
    
  2. static_cast

    用于各种隐式转换,比如非const转const,void*转指针等, static_cast能用于多态向上转化,如果向下转能成功但是不安全,结果未知;

    static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换,例如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
    ①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
    进行上行转换是安全的;
    进行下行转换时,由于没有动态类型检查,所以是不安全的。
    ②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
    ③把空指针转换成目标类型的空指针。
    ④把任何类型的表达式转换成void类型。
    注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性。

    基本类型数据转换:

    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属性
    

    类上行和下行转换(bp为父类Base指针,dp为子类Derived 指针):

    if(Derived *dp = static_cast<Derived *>(bp)){//下行转换是不安全的
    //使用dp指向的Derived对象  
    }
    else{
    //使用bp指向的Base对象  
    }
    
    if(Base*bp = static_cast<Derived *>(dp)){//上行转换是安全的
    //使用bp指向的Derived对象  
    }
    else{
    //使用dp指向的Base对象  
    }
    
  3. dynamic_cast

    用于动态类型转换。只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。向下转化时,如果是非法的对于指针返回NULL,对于引用抛异常。
    它通过判断在执行到该语句的时候变量的运行时类型和要转换的类型是否相同来判断是否能够进行向下转换。

    dynamic_cast<type*>(e)
    dynamic_cast<type&>(e)
    dynamic_cast<type&&>(e)
    

    type必须是一个类类型,在第一种形式中,type必须是一个有效的指针;在第二种形式中,type必须是一个左值;在第三种形式中,type必须是一个右值。在上面所有形式中,e的类型必须符合以下三个条件中的任何一个:e的类型是是目标类型type的公有派生类、e的类型是目标type的公有基类或者e的类型就是目标type的的类型。如果一条dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个std::bad_cast异常(该异常定义在typeinfo标准库头文件中)。e也可以是一个空指针,结果是所需类型的空指针。

    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对象  
    }
    

    值得注意的是,在上述代码中,if语句中定义了dp,这样做的好处是可以在一个操作中同时完成类型转换和条件检查两项任务。

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

    几乎什么都可以转,比如将int转指针,可能会出问题,尽量少用;

  5. 为什么不使用C的强制转换?

    C的强制转换表面上看起来功能强大什么都能转,但是转化不够明确,不能进行错误检查,容易出错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值