C++类型转换(static_cast,dynamic_cast,const_cast和reinterpret_cast)

一、概述

  • 类型转换(cast)是将一种数据类型转换成另一种数据类型。例如,如果将一个整型值赋给一个浮点类型的变量,编译器会暗地里将其转换成浮点类型(即 隐式转换 )。转换是非常有用的,但是它也会带来一些问题,比如在转换指针时,我们很可能将其转换成一个比它更大的类型,但这可能会破坏其他的数据。应该小心类型转换,因为转换也就相当于对编译器说:忘记类型检查,把它看做其它的类型。一般情况下,尽量少的去使用类型转换,除非用来解决非常特殊的问题。
  • 无论什么原因,任何一个程序如果使用很多类型转换都值得怀疑。
  • 标准 C++ 提供了一个 显式转换 的语法,来替代旧的 C语言 风格的类型转换。使用 C语言 风格的 强制类型转换 可以把想要的任何东西转换成我们需要的类型。那为什么还需要一个新的 C++ 类型的强制转换呢?新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++ 风格的强制转换其它的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道其强制转换的目的。
  • 这种 显示转换 的语法有四种,它们分别是:static_cast,dynamic_cast,const_cast和reinterpret_cast。

1、静态转换(static_cast)

  • 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
  • 用于 上行转换1,是安全的。
  • 用于 下行转换2,由于没有动态类型检查,所以是不安全的。
  • 用于基本数据类型之间的转换,如把 int 转换成 char,把 char 转换成 int。这种转换的安全性需要开发人员来保证。

2、动态转换(dynamic_cast)

  • dynamic_cast 主要用于类层次间的 上行转换1下行转换2
  • 在类层次间进行 上行转换1 时,dynamic_cast 和 static_cast 的效果是一样的。
  • 在进行 下行转换2 时,dynamic_cast 具有类型检查的功能,比 static_cast 更安全。

3、常量转换(const_cast)

  • 该运算符用来修改类型的 const 属性。
  • 常量指针被转化成非常量指针,并且仍然指向原来的对象;
  • 常量引用被转换成非常量引用,并且仍然指向原来的对象;
  • 注意:不能直接对非指针和非引用的变量使用 const_cast 操作符去直接移除它的 const。

4、重新解释转换(reinterpret_cast)

  • 这是最不安全的一种转换机制,最有可能出现问题。
  • 主要用于将一种数据类型从一种类型转换为另一种类型。它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针。

二、我自己对四种转换的总结整理

  • C语言强制类型转换,支持任意类型之间的转换,虽然用起来非常方便,但这种操作是极其不安全的。

  • 上行转换1下行转换2 图解及其安全性参见下图:

    在这里插入图片描述

  • 下例子中用到的类的声明和定义如下:

    class Animal{ cout<<"I'm a Animal."; };				//动物类
    class Cat : public Animal{ cout<<"I'm a Cat."; };	//猫
    class Apple{ cout<<"I'm a Apple"; };				//苹果
    
  • 注:下面所有示例代码中的注释,OK 表示这行代码可以正常编译通过,Error 表示报错/编译不通过

1、static_cast

  1. 主要用于父类和子类之间指针或引用的转换。

  2. 支持基本类型之间的转换。

    //static_cast 作用于基本数据类型
    char ch='c';
    double d1=(double)ch;								//C语言强制类型转换,OK
    double d2=static_cast<double>(ch);					//静态转换,OK
    
  3. 支持 上行转换1 ,是安全的。

    //static_cast 作用于自定义类型(结构体、类)
    //作用于有关系的类(父类和子类)之间
    //1.上行转换(安全)
    Animal *animal=static_cast<Animal *>(new Cat);		//静态转换,OK
    
  4. 支持 下行转换2 ,是不安全的。

    //static_cast 作用于自定义类型(结构体、类)
    //作用于有关系的类(父类和子类)之间
    //2.下行转换(不安全,容易访问越界)
    Cat *cat=static_cast<Cat *>(new Animal);			//静态转换,OK
    
  5. 不支持没有关系的类之间的指针或引用的转换,保证了安全性。

    Animal *animal_1=(Animal *)(new Apple);				//C语言强制类型转换,OK(不安全)
    Animal *animal_2=static_cast<Animal *>(new Apple);	//静态转换,Error
    

2、dynamic_cast

  1. 主要用于父类和子类之间指针或引用的转换。

  2. 不支持基本类型之间的转换。

    char ch = 'c';
    double d1 = (double)ch;								//C语言强制类型转换,OK
    double d2 = dynamic_cast<double>(ch);				//动态转换,Error
    
  3. 支持 上行转换1 ,是安全的。

    Animal *animal=dynamic_cast<Animal *>(new Cat);		//动态转换,OK
    
  4. 不支持 下行转换2 ,相比 static_cast 保证了安全性。

    Cat *cat=dynamic_cast<Cat *>(new Animal);			//动态转换,Error
    
  5. 不支持没有关系的类之间的指针或引用的转换,保证了安全性。

    Animal *animal=dynamic_cast<Animal *>(new Apple);	//动态转换,Error
    

3、const_cast

  1. 用于修改类型的const属性。

    int *p=nullptr;
    const int *p1=(const int *)p;						//C语言强制类型转换,OK
    const int *p2=const_cast<const int *>(p);			//常量转换,OK
    
  2. 常量指针转非常量指针,仍指向原来的对象。

    const int *p=nullptr;
    int *p1=p;											//直接转换(隐式转换),Error
    int *p2=(int *)p;									//C语言强制类型转换,OK
    int *p3=const_cast<int *>(p);						//常量转换,OK
    
  3. 常量引用转非常量引用,仍指向原来的对象。

    int num=10086;
    //常量引用转普通引用(非常量引用)
    const int &ob=num;
    int &ob2=ob;										//直接转换(隐式转换),Error
    int &ob3=(int &)ob;									//C语言强制类型转换,OK
    int &ob4=const_cast<int &>(ob);						//常量转换,OK
    
  4. 不能对非指针或非引用的变量用const_cast移除它的const属性。

    const int a=10086;
    int b=a;											//直接转换(隐式转换),OK
    int b1=(int)a;										//C语言强制类型转换,OK
    int b2=const_cast<int>(a);							//常量转换,Error
    

4、reinterpret_cast

  1. 是最不安全的的一种类型转换方式,顾名思义,就是将一种类型转换为另一种类型,比如int转为int*,int*转为int(类似于C语言强制类型转换,但不完全相同)。

  2. 不支持基本类型间的转换。

    char ch='c';
    double d1=(double)ch;								//C语言强制类型转换,OK
    double d2=reinterpret_cast<double>(ch);				//重新解释转换,Error
    
  3. 支持不相关类型间的转换,不安全。

    Animal *p=reinterpret_cast<Animal *>(new Apple);	//重新解释转换,OK
    
  4. 支持 上行转换1 ,安全。

    Animal *p=reinterpret_cast<Animal *>(new Cat);		//重新解释转换,OK
    
  5. 支持 下行转换2 ,不安全。

    Cat *cat=reinterpret_cast<Cat *>(new Animal);		//重新解释转换,OK
    

三、脚注与版权声明

以上部分内容引用自千峰梁何大佬的课件,仅供参考学习,侵删。

参考链接:6.00 static cast静态转换_bilibili

如有错误或者遗漏的地方欢迎各位大佬补充指正!

创建日期:2022年08月20日 AM.


  1. 上行转换:把派生类的指针或引用转换成基类表示,换句话说就是把基类(父类)指针指向派生类(子类)空间(一般来说,子类是基于父类进行了扩展,所以可以理解为小指针指向大空间,是安全的)。 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  2. 下行转换:把基类的指针或引用转换成派生类表示,换句话说就是把派生类(子类)指针指向基类(父类)空间(一般来说,子类是基于父类进行了扩展,所以可以理解为大指针指向小空间,这样可能会访问越界,所以是不安全的)。 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
static_castdynamic_castreinterpret_cast是C++中的类型转换操作符。 static_cast用于基本类型的强制转换,以及非多态类型的指针或引用之间的转换。它可以将一种类型转换为另一种类型,例如将int转为float,char转为int等。同时,static_cast还可以将指向基类的指针转换为指向子类的指针,但是不能将const对象转换为non-const对象。 dynamic_cast用于在运行时进行类型检查和转换。它主要用于类层次结构中的多态类型之间的转换dynamic_cast可以将指向基类的指针或引用转换为指向派生类的指针或引用。在转换过程中,dynamic_cast会进行类型检查,如果转换失败,则返回nullptr(对于指针)或抛出std::bad_cast异常(对于引用)。 reinterpret_cast是一种较为底层的类型转换操作符,它可以将任意类型的指针或引用转换为其他类型的指针或引用。它不进行类型检查,因此需要谨慎使用。reinterpret_cast主要用于处理一些底层的操作,例如将指针转换为整数类型、将指针转换为void指针等。 需要注意的是,reinterpret_castconst_cast都属于较为底层的类型转换操作符,使用它们需要谨慎,因为它们可能会导致类型不匹配或打破类型系统的一些规则。在使用类型转换操作符时,应该确保转换是安全且符合语义上的合理性。 引用:C++中的类型转换static_castdynamic_castconst_castreinterpret_cast总结 引用:const_cast,dynamic_cast,reinterpret_cast,static_cast四种转换的区别 引用:const_cast用来将对象的常量属性转除,使常量可以被修改 引用:static_cast用来处理隐式转换,等同于C语言中的(NewType)Expression强转<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值