C++的四种转换运算符

本文详细介绍了C++中四种类型的转换操作:static_cast、dynamic_cast、const_cast和reinterpret_cast。通过实例解析了每种转换的特点及应用场景,如static_cast用于编译期类型转换,dynamic_cast用于运行时类层次间的类型转换等。
摘要由CSDN通过智能技术生成
  • C++有四种自带的转型操作

参考:C++ static_cast、dynamic_cast、const_cast和reinterpret_cast(四种类型转换运算符)

  • 语法格式:xxx_cast<newType>(data)  将data转换为newType,根据data的不同对应xxx_cast
  • static_cast:static_cast 不能用于无关类型之间的转换,static_cast 是“静态转换”的意思,也就是在编译期间转换,转换失败的话会抛出一个编译错误。
//老式转换
double scores = 95.5;
int n = (int)scores;

//新的转换格式
double scores = 95.5;
int n = static_cast<int>(scores);
  • const_cast 比较好理解,它用来去掉表达式的 const 修饰或 volatile 修饰。换句话说,const_cast 就是用来将 const/volatile 类型转换为非 const/volatile 类型。
const int n = 100;
int *p = const_cast<int*>(&n);
  • reinterpret_cast:  reinterpret 是“重新解释”的意思,顾名思义,reinterpret_cast 这种转换仅仅是对二进制位的重新解释,不会借助已有的转换规则对数据进行调整,非常简单粗暴,所以风险很高。和static_cast很象,都是强转的意思,因此都不太安全。

    char str[]="http://c.biancheng.net";
    float *p1 = reinterpret_cast<float*>(str); //把内存中的str[]按float的方式来解释吗可以转换,但不安全
  • dynamic_cast :dynamic_cast 用于在类的继承层次之间进行类型转换,它既允许向上转型(Upcasting),也允许向下转型(Downcasting)。向上转型是无条件的,不会进行任何检测,所以都能成功;向下转型的前提必须是安全的,要借助 RTTI 进行检测,所有只有一部分能成功。

class Base {
public:
    virtual void foo() {} //必须含有虚函数,否则不能执行dynamic_cast
};
 
class Derived :public Base {};
 
int main()
{
    Base *bp = new Base;
 
    //成功返回Derived指针,失败返回0
    if (Derived *dp = dynamic_cast<Derived*>(bp))  //局部dp保证了dp只能作用于if { ... }
    {
	    //使用dp指向的Derived对象
    }
    else 
    {
		//使用bp指向的Base对象
    }
 
    return 0;
}

(1)向上转型(Derived类转Base类):都是允许的,因为继承,向上转型肯定是可以的。

(2)向下转型(Base类转Derived类):Derived *dp = dynamic_cast<Derived*>(bp);一看就是不安全的,将Base类转向Derived类,幸好dynamic_cast提供了检测机制,如果Derived *dp = dynamic_cast<Derived*>(bp)转换失败,dp是0

(3)对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用

(4)对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针

(5)只有真正的Derived对象才可以被向下转型,例如:

#include<iostream>
using namespace std;

class Base
{
    //something
    public:
        // dynamic_cast只有在类有虚函数时才会进行类型检查,所以要使用dynamic_cast就需要定义虚函数
        virtual void print() { cout<<"I'm Base!"<<endl;}
};

class Sub: public Base
{
    //something
    public:
        virtual void print() { cout<<"I'm Sub!"<<endl;}
};

int main()
{
    Sub sub2;
    // 基类到派生类的向下转换
    // 此时,只有基类指针运行是真正指向继承类才能转换成功
    Base base2;
    Sub* sub_ptr2=dynamic_cast<Sub*>(&base2);
    if(sub_ptr2!=NULL){     //此时转换失败 ,sub_ptr2是NULL
        sub_ptr2->print();
    }
    cout<<"sub ptr2:"<<sub_ptr2<<endl;  //输出: sub ptr2:0x0
    Base* base3=&sub2;
    Sub* sub_ptr3=dynamic_cast<Sub*>(base3);
    if(sub_ptr3!=NULL){
        sub_ptr3->print();              //输出: I'm Sub!
    }
    cout<<"sub ptr3:"<<sub_ptr3<<endl;  //输出: sub ptr3:0x7ffee2665438

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值