【C++】类型转换(静态转换 动态转换 常量转换 重新解释转换)

类型转换概念

类型转换(cast)是将一种数据类型转换成另一种数据类型。
例如,如果将一个整型值赋给一个浮点类型的变量,编译器会暗地里将其转换成浮点类型(隐式类型转换)。

转换是非常有用的,但是它也会带来一些问题,比如在转换指针时,我们很可能将其转换成一个比它更大的类型,但这可能会破坏其他的数据。(指针步长与偏移量等因素导致)

c++提供了一个显示的转换的语法,来替代旧的C风格的类型转换。(静态、动态、常量、重新解释)

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。

C++层次转换规则

C++中层次类型转换中无非两种:上行转换和下行转换

C++规定自定义类型数据如果发生了继承关系,编译器允许进行类型转换(向上转型、向下转型),否则不能进行类型转换

静态转换(static_cast)(编译时类型检查)

语法

静态转换需要用C++内置函数模板static_cast( expression )

static_cast < T > ( expression ),该运算符把expression转换为T类型,但没有运行时类型检查来保证转换的安全性

作用

  1. 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
    在这里插入图片描述
    C++规定自定义类型数据如果发生了继承关系,编译器允许进行类型转换(向上转型、向下转型),否则不能进行类型转换转换将会失败

    进行上行转换(把派生类的指针或引用转换成基类表示)是安全的
    基类指针步长相对于派生类指针步长来说较小,并不会超出派生类范围访问其他数据
    进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
    基类指针步长相对于派生类指针步长来说较小,使用派生类指针访问基类对象,可能会超出范围
  2. 用于基本数据类型之间的转换,如把int转换成char,把char转换成int(这种转换的安全性也要开发人员来保证)
    在这里插入图片描述

动态转换(dynamic_cast)(运行时类型检查)

作用

dynamic_cast主要用于类层次结构中父类和子类之间指针和引用的转换(上行转换和下行转换)
在这里插入图片描述

在类层次间进行上行转换时(安全的转换),dynamic_cast和static_cast的效果是一样的

在进行下行转换时(不安全,子类指针可能会超出基类对象),dynamic_cast具有类型检查的功能,比static_cast更安全

dynamic_cast不能作用于基本数据类型
在这里插入图片描述

语法

动态转换需要用C++内置函数模板dynamic_cast( expression )

dynamic_cast< T > ( expression ),该运算符把expression转换为T类型,具有运行时类型检查,因此可以保证下行转换的安全性
安全性,即转换成功就返回转换后的正确类型指针,如果转换失败,则返回NULL,之所以说static_cast在下行转换时不安全,是因为即使转换失败,它也不返回NULL。

动态转换的运行时类型检查

dynamic_cast运行时会进行类型检查,且检测非常严格,失去精度或不安全的转换均无法进行

上行转换中,基类指针指向派生类对象,派生类中有基类中所有成员(属性和方法),还有自定义的成员,所有派生类的大小至少大于基类,因此基类指针步长小于派生类指针步长,所以使用基类指针访问派生类成员时并不会超出派生类对象范围,因此时安全的

下行转换中,派生类指针指向基类对象,派生类中有基类中所有成员(属性和方法),还有自定义的成员,所有派生类的大小至少大于基类,因此派生类指针步长大于基类指针步长,所以使用派生类指针指向基类对象时可能会发生超出基类对象范围访问其他地址问题,因此时不安全的

下行转换是不安全的,在运行时可能会有问题,因为子类中包含父类中没有的数据和函数成员,如果去访问子类中有但父类中没有的成员,就会出现访问越界的错误,导致程序崩溃,动态转型(dynamic_cast)由于具有运行时类型检查功能,转换时将会检测被转换对象的类型,下行转换将会失败,返回NULL

   发生多态情况例外,多态是使用基类指针指向子类对象(上行转型),从而调用子类方法,这种情况下可以使用动态转换再将指向子类对象的父类指针转换成子类指针
在这里插入图片描述

常量转换(const_cast)

作用

常量转换用来修改类型的const属性,即将非常量(指针/引用)转换为常量(指针/引用),将常量(指针/引用)转换为非常量(指针/引用)
在这里插入图片描述
不能直接对非指针和非引用的变量使用const_cast操作符去直接添加/移除它的const,只能操作指针或引用数据
在这里插入图片描述

注意

常量指针被转化成非常量指针,并且仍然指向原来的对象(常量符号表中对象);
常量引用被转换成非常量引用,并且仍然指向原来的对象(常量符号表中对象);

语法

常量转换需要用C++内置函数模板const_cast( expression )

const_cast< T > ( expression ),该运算符把expression转换为T类型

重新解释转换(reinterpret_cast)

重新解释转换是最不安全的一种转换机制,最有可能出问题。

重新解释转换用于将一种数据类型从一种类型转换为另一种类型

它甚至可以:

将一个指针转换成一个整数,也可以将一个整数转换成一个指针.
在这里插入图片描述

将没有继承关系的类相互层次转换
在这里插入图片描述

语法

重新解释转换需要用C++内置函数模板reinterpret_cast( expression )

reinterpret_cast< T > ( expression ),该运算符把expression转换为T类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

列队猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值