C++四种类型转换运算符的个人总结

2023-05-16

在这四种类型转换符包括static_cast、dynamic_cast、reinterpret_cast、const_cast其中使用比较多的是dynamic_caststatic_cast。我们就从这两种类型转换符开始谈起。

一、static_cast
该类型转换符主要应用于普通数据类型和具有继承关系的类的指针和引用的转换,不能进行两个完全不相干的类型或者两个不同类型指针或引用的转换。

	int * ptr_a = &a;
	double* ptr_db = &bd;
	//编译器报错
	double* test = static_cast<double*>(ptr_a);

普通类型的数据之间进行转换,有可能转换后的数据会将原本的数据截断,导致数据不完全,这就要程序员自己去发现这种风险,编译器不会报错。

而对于具有继承关系类指针和引用的转换需要注意几点:

  • 使用static_cast向上转换,即将派生类指针、引用转换成基类的指针或者引用是安全的,以为派生类始终包含着基类。
  • 使用static_cast向下转换是不安全的,但是编译器是允许的,不进行错误检查。之所以不安全是因为不能确保转换后的指针和引用确实是指向一个派生类对象的。有可能这个指针和引用实际指向的就是基类对象,强制转换成指向派生类的对象后,这个指针或引用也不具备派生的数据和成员,也不能调用派生类的方法。(转换后指针包含的增加的内存存储的东西是未知的),dynamic_cast在继承关系的类指针引用转换的时候就会进行安全检查。

二、dynamic_cast

dynamic_cast最主要的作用就是将基类指针引用转换成派生类指针引用去调用专属于派生类的非虚方法,或者是专有的虚方法。

dynamic_cast只能用于具有继承关系的类的指针和引用的转换。

  • 当向上转换时,是完全安全的。
  • 在向下转换时(必须确保具有多态继承关系,即基类必须具有虚函数),且要确保被转换的指针或者引用确实是指向一个被转换类型的对象。

首先考察继承关系的类之间没有多态关系

class Base {
public:
};

class Derived:public Base {
};

int main() {

	Base a;
	Derived d;

	Base* ptr1 = &a;
	Base* ptr2 = &d;
	Derived* ptr3 = &d;

	Base& ref = d;
	Base& ref2 = d;
	Derived& ref3 = d;

	Base* temp = dynamic_cast<Base*> (&d);//向上转换,安全
	
	//不具备多态类继承关系,也就是基类并没有虚函数,将基类指针
	//转换成派生类指针是没有意义的
	Derived* temp2 = dynamic_cast<Derived*> (ptr2);
	Derived& temp3 = dynamic_cast<Derived&>(ref2);
	
	//将基类中增加一个虚函数dynamic_cast就不会报错了,
	//因为别转换的类型具备多态属性了
}

上述结论表明:dynamic_cast是要进行运行时安全检查的,将不具备多态继承关系的基类指针或引用向下转换成派生类指针或引用,dynamic_cast会报错,表明它向下转换的类型必须具有多态属性。

在来考察基类和派生类具有多态属性的情况:

class Base {
public:
	virtual void test(){}
};

class Derived:public Base {
	void test(){}
};

class Derived2 :public Base {

};

int main() {

	Base a;
	Derived d;

	Base* ptr1 = &a;
	Base* ptr2 = &d;
	Derived* ptr3 = &d;

	Base& ref = d;
	Base& ref2 = d;
	Derived& ref3 = d;

	Base* temp = dynamic_cast<Base*> (ptr3);
	
	//这两句将不会再报错
	Derived* temp2 = static_cast<Derived*> (ptr2);
	Derived& temp3 = dynamic_cast<Derived&>(ref2);

	Derived2* temp4=dynamic_cast<Derived2*>(ptr2);
	//这个转换会失败,因为ptr2实际指向的是一个Derived对象
	//而不是Derived2对象,这样的转换不安全,编译器
	//会报错
}

根据上述情况我们又可以得出结论:dynamic_cast向下转换,必须转换成被转换指针或引用实际指向的对象的指针或引用才行。
dynamic_cast<type_id>(expression)中expression实际指向的对象要与type_id指向的对象类型相同

所以、结合上述两点的情况。

  1. dynamic_cast会执行运行时检错,如果继承类中没有多态属性,则在向上转换时可以使用dynamic_cast,也可以使用static_cast,这两个类型转换在向上转换时都是安全的。在向下转换时,则要考虑dynamic_cast会报错,被转换的指针或引用只想的对象必须具有多态性才能向下转换,而使用static_cast是不会报错的,但不安全。
  2. 在具有多态属性的继承类中,向上转换都是安全的。但是在向下转换时,如果没有转换到dynamic_cast<type_id>(expression)中expression实际指向的类型的指针或引用时,会转换失败,指针的话会返回空指针,引用的话会抛出异常。

三、reinterpret_cast
reinterpret_cast常用于将两个不相关类型的转换、或是两个指针类型之间的转换、或是整型和指针之间的转换。
这种类型的转换就是重新对内存的存储形式进行改变,例如将整型转换为指针,就是将整型的四个字节重新解释为一个指针, 指向一个内存。
或是将一个指针转换为另外一个指针,对指针指向的内存做重新解释(或是切割,或是增长)。

四、const_cast
主要用于对常指针或常引用来取出const限定符。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++四种类型转换运算符的个人总结 的相关文章

  • Ubuntu unzip 安装

    ubuntu unzip 安装以及命令参数说明 安装命令 xff1a sudo apt get install unzip 解压 zip文件命令 xff1a unzip unzip命令能够将被winzip压缩的文件解压 unzip命令的执行
  • 新建git仓库管理项目并更新代码提交git

    新建git仓库 第一步 xff1a 登录上自己的git后台 xff0c 在我的工作台的左下角 xff0c 点击仓库旁边的 43 号 xff0c 创建一个新的仓库 xff1a 第二步 xff1a 在新建仓库界面完善仓库的信息 xff0c 这里
  • CMake是什么?有什么用

    CMake CMake是一个跨平台的编译 Build 工具 可以用简单的语句来描述所有平台的编译过程 CMake能够输出各种各样的makefile或者project文件 xff0c 能测试编译器所支持的C 43 43 特性 类似UNIX下的
  • PX4系统学习

    PX4系统学习 扑翼飞行器的硬件组成飞控板电调电调的分类 舵机 扑翼飞行器的硬件组成 要了解学会二次开发首先要知道 xff0c 手头的飞行器的硬件结构 以及各个部分的结构是有何种作用的 xff0c 这样才能在根本上了解编程逻辑 xff0c
  • rostopic echo --noarr查看激光雷达数据详细信息(如frame_id)

    用rostopic echo 激光雷达话题名查看激光雷达返回的数据 xff0c 除了数字什么也显示不出来 想要查看激光雷达数据的frame id等信息 xff0c 加上 noarr参数即可 xff0c 排除话题数据中的数组信息 如图二所示
  • Django基本数据访问

    当需要操作数据时 xff0c 不再需要通过SQL语句 xff0c Django自动为这些模型提供了高级的Python API 接下来联系数据库表的操作 xff0c 运行manage py提供的shell语句 guest gt python3
  • SVO2.0 安装编译

    SVO2 OPEN https github com uzh rpg rpg svo pro open git挂梯子 https blog csdn net qq 33349365 article details 101514412 如果各
  • k8s(一)—pod管理、资源清单编写

    1 pod管理 k8s官方文档 root 64 server2 kubectl run nginx image 61 nginx 运行一个容器 xff0c 镜像为nginx pod nginx created root 64 server2
  • k8s(三)—控制器(replicaset、deployment、daemonset、job、cronjob)

    1 控制器简介 2 Replicaset控制器 root 64 server2 vim rs yaml apiVersion apps v1 kind ReplicaSet metadata name replicaset example
  • k8s(四)—service服务(暴露方式:ClusterIP、NodePort、LoadBalancer、ExternalName、ingress)

    1 service简介 2 开启kube proxy的ipvs root 64 server2 kubectl n kube system get pod grep proxy 每个节点都有haproxy kube proxy d6cp2
  • k8s(五)—容器间的网络通信

    1 同一节点不同pod之间的通信原理 root 64 server2 kubectl get pod o wide 查看pod 的ip NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NOD
  • k8s(七)—statefullset部署mysql主从集群

    1 使用statefullset部署mysql主从集群 mysql 0是master mysql 1和mysql 2是两个备份 当mysql写的时候 xff0c 找headless service中的mysql 0 mysql xff1b
  • k8s(十)— 资源限制(cpu、memory)

    1 k8s容器资源限制简介 2 k8s容器资源限制实施 2 1 内存限制示例 root 64 server1 docker search stress 搜索测试镜像stress NAME DESCRIPTION STARS OFFICIAL
  • k8s(十二)— HPA

    HPA官网 从最基本的角度来看 xff0c Pod 水平自动扩缩控制器根据当前指标和期望指标来计算扩缩比例 期望副本数 61 ceil 当前副本数 当前指标 期望指标 例如 xff0c 如果当前指标值为 200m xff0c 而期望值为 1
  • k8s(十四)—高可用集群部署

    1 部署k8s高可用原理图 2 清理环境 root 64 server2 helm kubectl drain server4 下线server4 root 64 server2 helm kubectl delete nodes serv
  • oracle数据库控制语言—DCL

    文章目录 1 授予系统权限1 1 授予创建其他对象权限 2 撤销系统权限2 1 示例 3 oracle 中的角色3 1 什么时角色3 2 创建角色并且授予权限给角色3 2 1 创建角色3 2 1 1 示例 3 2 2 授予权限给一个角色3
  • 软件测试 | Django插入数据

    gt gt gt from datetime import datetime gt gt gt el 61 Event id 61 2 name 61 39 红米 Pro 发布会 39 xff0c limit 61 2000 status
  • oracle数据库的导入与导出

    文章目录 1 oracle数据库导入与导出需要注意2 导出数据格式介绍3 传统方式exp 导出 xff09 和 xff08 imp xff09 导入3 1 命令执行方式3 2 命令格式3 3 导出数据3 3 1示例 3 4 导入数据3 4
  • oarcle — ANY和ALL、行列转换、递归查询

    文章目录 1 在多行子查询中用ANY运算符1 1 示例 2 在多行子查询中用ALL运算符2 1 示例 3 行列转换3 1 建表3 2 插数3 3 列传行3 3 1 union all 实现列传行3 3 2 oracle 自带函数 3 4 行
  • 嵌入式学习规划

    一 STM32的单片机 1 学习stm32开发板 1 1 流水灯 学习内容 xff1a xff1a 工程建立 xff0c 库的使用 1 2 AD采集 学习内容 xff1a xff1a 学习AD 1 3 串口 学习内容 xff1a xff1a

随机推荐

  • UAV Ubuntu18.04 PX4环境搭建

    Ubuntu18 04 PX4环境搭建 设备 VMware WorkStation16 0pro Ubuntu18 04 虚拟机 参考链接 XTDrone团队的 xff1a 仿真平台基础配置 xff08 PX4 1 11版 xff09 ht
  • 无人机遥控器使用说明

    遥控器使用说明 21 06 09 激光雷达避障使用时候设置的通道 开机前检查 所有拨码开关拨到最上方 SWA SWB两个开关 暂时没用 主要使用SWC和SWD 开机 同时按下两个开机键开机 模式说明 现在使用的模式主要设置了四个 红框 SW
  • Jetson Tx2配置PX4飞控实机开发环境

    Jetson Tx2使用 设备 Jetson Tx2板卡 xff08 原装或者底板加核心板 xff09 带Ubuntu系统电脑或者虚拟机Tx2原装数据线HDMI显示器鼠标键盘 刷机 参考链接 1 使用NVIDIA SDK Manager刷机
  • Jetson Nano刷系统教程

    Jetson Nano使用 设备 Jetson Nano板卡64G SD卡 xff08 最小16G xff09 读卡器HDMI显示器鼠标键盘 刷机 格式化SD卡 使用SD卡格式化工具进行格式化 下载镜像 进入英伟达下载中心 xff1a ht
  • 【Windows下搭建深度学习环境之TensorFlow篇】一气呵成,五步搞定TensorFlow的安装!TensorFlow的安装之路

    TensorFlow的安装之路 0 安装前须知1 安装Anaconda1 1 什么是虚拟环境 xff1f 1 2 安装Anaconda具体步骤1 3 添加环境变量 xff08 系统变量 xff09 1 4 修改Conda库和pip库的安装源
  • 关于putty出现access denied的问题解决方案

    关于putty出现access denied的问题解决方案 1 网上也说了很多 比较多一点的就是修改PermitRootLogin 在linux终端terminal执行下面命令 sudo gedit etc ssh sshd config
  • [四旋翼无人机PID仿真(一)

    64 四旋翼无人机串级PID仿真 四旋翼无人机的数学模型的建立 xff1a 在建立模型的过程中 xff0c 采用了欧拉角来进行数学模型的建立 首先进行无人机结构以及飞行原理的分析 xff0c 然后进行系统建模 xff0c 在建模的过程中 x
  • Django查询、删除、更新数据

    查询数据 查询无疑是数据库表中使用频率最高的操作 table object get 方法用于从数据库表中取得一条匹配的结果 xff0c 返回一个对象 xff0c 如果记录不存在的话 xff0c 那么它会报DoesNotExist类型错误 通
  • static 静态方法可以直接调用,不用创建对象

    static 静态方法可以直接调用 xff0c 不用创建对象
  • Java歌手评分系统

    有五个评委 xff0c 对一个歌手唱歌打分 xff0c 最终得分要求去掉最高分去掉最低分 xff0c 求平均分 注意要求的格式为 xff1a 输入第1个评委给分 97 1 输入第2个评委给分 89 2 输入第3个评委给分 88 6 输入第4
  • python3环境下使用cv_bridge

    环境 ubuntu18 04 ros melodic 由于ros自带的python版本是2 7 系统中的cv bridge是用python2编译的 xff0c 如果在python3环境中使用cv bridge xff0c 会报以下错误 xf
  • 运行VINS-MONO报的错

    刚刚安装完环境 xff0c 已经可以跑通Euroc数据集 xff0c 回忆一下值得记下来的注意事项 环境配置 我的电脑 xff1a Ubuntu18 04 ROS melodic Opencv3 4 3 首先 xff1a GitHub上的代
  • TX2安装realsense SDK和librealsense

    官网https github com IntelRealSense librealsense安装很简单 xff0c 一定要对应好SDK与ros包 realsense固件的版本 https github com IntelRealSense
  • VINS-Fusion轨迹评估

    代码轨迹输出修改 visualization cpp VINS Fusion master vins estimator src utility visualization cpp的150行左右 xff1a span class token
  • antd4中Form组件initialValues设置初始值无效,使用setFieldsValue动态赋值,getFieldsValus动态获取值

    首先说明initialValues这个属性 xff0c 这个属性antd官方给的是设置Form组件初始值 xff0c 但是有个问题如果值从后端请求那么initialValues可能会设置不上 xff0c 如果说用匿名组件的话 xff0c 修
  • 一个存放论文、笔记等的github仓库

    link xff1a PaperNote如果好用 xff0c 请给个star哦
  • 关于C++ Overload、Override、hide的一些总结

    一 override和overload区别 当需要一些相同的函数名接受不同的参数实现不同的功能时 xff0c 可以是运用函数重载来实现 但是 xff0c 函数的重载必须要在同一个作用域内重载 xff0c 才叫做重载 在不同作用域的两个同名函
  • C++多态的个人总结

    多态 多态分为运行时多态和编译期多态 xff0c 也被称作动态绑定和静态绑定或者晚绑定和早绑定 一 编译期多态 编译期多态主要是通过函数重载 xff0c 运算符重载还有模板函数 xff0c 模板类来是实现的 函数重载和运算符重载 xff0c
  • 嵌入式linux截图工具gsnap移植到OK6410 TX2416开发板

    交叉编译器版本 xff1a arm linux gcc 4 3 2 操作系统平台 xff1a Ubuntu 11 04 开发板平台 xff1a Tx2416 OK6410开发板 需要以下两个源文件 jpegsrc v6b tar gz gs
  • C++四种类型转换运算符的个人总结

    在这四种类型转换符包括static cast dynamic cast reinterpret cast const cast其中使用比较多的是dynamic cast和static cast 我们就从这两种类型转换符开始谈起 一 stat