【C++】C++的类型转换

C++的类型转换

  • 一、C语言中的类型转换
  • 二、C++的类型转换
    • 1、static_cast
    • 2、reinterpret_cast
    • 3、const_cast
    • 4、dynamic_cast
  • 三、RTTI

一、C语言中的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。

  • 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败,注意:只有相近类型之间才能发生隐式类型转换
  • 显式类型转化:需要用户自己处理

例如:比如intdouble表示的都是数值,只不过它们表示的范围和精度不同。而指针类型表示的是地址编号,因此整型和指针类型之间不会进行隐式类型转换,如果需要转换则只能进行显式类型转换。

void Test()
{int i = 1;// 隐式类型转换double d = i;printf("%d, %.2f\n", i, d);int* p = &i;// 显示的强制类型转换int address = (int)p;printf("%x, %d\n", p, address);
}

C语言类型转换的优缺点:

C风格的转换格式很简单,但还是有不少缺点的:

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰

C语言转换的可视性比较差,相近类型之间发生隐式类型转换,难以跟踪错误的转换。

因此C++为了加强类型转换的可视性,提出了自己的类型转化风格,因为C++要兼容C语言,所以C++中还可以使用C语言的转化风格。

二、C++的类型转换

标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:
static_castreinterpret_castconst_castdynamic_cast

1、static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。

int main()
{double d = 10.21;int i = static_cast<int> (d);cout << i << " " << d << endl;// 转换失败//int* p = static_cast<int*> (i);//cout << p << endl;return 0;
}

2、reinterpret_cast

reinterpret_cast操作符通常为重新解释,用于将一种类型转换为另一种不同的类型。

int main()
{// 转换失败//double d = 10.21;//int i = reinterpret_cast<int> (d);//cout << i << " " << d << endl;// 转换成功int a = 10;int* p = reinterpret_cast<int*> (a);cout << p << endl;return 0;
}

在这里插入图片描述

3、const_cast

const_cast最常用的用途就是删除变量的const属性,方便赋值,注意const_cast<><>里面必须是指针或者引用类型。

int main()
{const int a = 10;int* pa = const_cast<int*> (&a);*pa = 20;cout << " a :" << a << endl;cout << "*pa :" << *pa << endl;return 0;
}

在这里插入图片描述

可能看到这个结果你会很不解,明明我们都已经修改了a,为什么打印的结果还是10?

解释一下:

  • 由于编译器认为const修饰的变量是不会被修改的,因此会将const修饰的变量存放到寄存器当中,当需要读取const变量时就会直接从寄存器中进行读取,而我们修改的实际上是内存中的a的值,因此最终打印出a的值是未修改之前的值。
  • 如果不想让编译器将const变量优化到寄存器当中,可以用volatile关键字对const变量进行修饰,这时当要读取这个const变量时编译器就会从内存中进行读取,即保持了该变量在内存中的可见性。
int main()
{volatile const int a = 10;int* pa = const_cast<int*> (&a);*pa = 20;cout << " a :" << a << endl;cout << "*pa :" << *pa << endl;return 0;
}

在这里插入图片描述

4、dynamic_cast

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)

  • 向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
  • 向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

而向下转型分为两种情况:

  1. 如果父类的指针(或引用)指向的是一个父类对象,那么将其转换为子类的指针(或引用)是不安全的,因为转换后可能会访问到子类的资源,而这个资源是父类对象所没有的。

  2. 如果父类的指针(或引用)指向的是一个子类对象,那么将其转换为子类的指针(或引用)则是安全的。

使用C风格的强制类型转换进行向下转型是不安全的,因为此时无论父类的指针(或引用)指向的是父类对象还是子类对象都会进行转换。

而使用dynamic_cast进行向下转型则是安全的。

  • 如果父类的指针(或引用)指向的是子类对象那么dynamic_cast会转换成功。
  • 如果父类的指针(或引用)指向的是父类对象那么dynamic_cast会转换失败并返回一个空指针
class A
{
public:virtual void f(){}
private:int _a;
};class B : public A
{
private:int _b;
};int main()
{A aa;B bb;A* pa = &aa;A* pb = &bb;cout << "强制类型转换, 父转子pa:" << (B*)pa << endl;cout << "强制类型转换, 父转子pb:" << (B*)pb << endl;cout << "---------------------------------------" << endl;cout << "dynamic_cast类型转换, 父转子pb:" << dynamic_cast<B*>(pa) << endl;cout << "dynamic_cast类型转换, 父转子pb:" << dynamic_cast<B*>(pb) << endl;
}

在这里插入图片描述

注意:

  1. dynamic_cast只能用于父类含有虚函数的类

  2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

三、RTTI

RTTI:Run-time Type identification的简称,即:运行时类型识别
C++通过以下方式来支持RTTI:

  1. typeid运算符
  2. dynamic_cast运算符
  3. decltype

4中类型转化的应用场景:

  • static_cast用于相近类型的类型之间的转换,编译器隐式执行的任何类型转换都可用static_cast
  • reinterpret_cast用于两个不相关类型之间的转换。
  • const_cast用于删除变量的const属性,方便赋值。
  • dynamic_cast用于安全的将父类的指针(或引用)转换成子类的指针(或引用)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/87102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dedecms tag 伪静态 数字版本

织梦伪静态将tag标签的url设置成id的方法&#xff1a; 1、在网站根目录下的tags.php中18行找到&#xff1a; if(isset($tags[2])) $PageNo intval($tags[2]);在其下方加入代码&#xff1a; $tagid intval($tag); if(!empty($tagid)) {$row $dsql->GetOne("SELECT …

【Vue】VUE常用的几种import引入方式

VUE常用的几种import引入方式 1、什么是组件 都说Vue是组件化开发&#xff0c;确实有道理&#xff0c;别说按钮输入框这种组件了&#xff0c;就连每个页面&#xff0c;从本质来看也是一个个组件&#xff0c;所以目标很明确&#xff0c;拿来就能用&#xff0c;有一定使用规范和…

【力扣每日一题】2023.9.23 树上的操作

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 这是一道程序设计类的题目&#xff0c;题目比较长&#xff0c;我稍微概括一下。 构造函数中给我们一个数组&#xff0c;第i个元素表示第…

3D目标检测实战 | 图解KITTI数据集与数据格式

目录 1 数据集简介2 传感器坐标系3 数据集下载与组织4 数据内容说明4.1 矫正文件calib4.2 图像文件image4.3 点云文件velodyne4.4 标签文件label4.5 平面文件plane 1 数据集简介 KITTI数据集是一个广泛应用于自动驾驶和计算机视觉领域的公开数据集。该数据集由德国卡尔斯鲁厄理…

Springboot 集成WebSocket作为客户端,含重连接功能,开箱即用

使用演示 public static void main(String[] args) throws Exception{//初始化socket客户端BaseWebSocketClient socketClient BaseWebSocketClient.init("传入链接");//发送消息socketClient.sendMessage("填写需要发送的消息", (receive) -> {//这里…

牛客java训练题 day1

9.24 day1 Q 1. this 指针是用来干什么的&#xff1f; 2.基类和派生类分别是指什么&#xff1f; 3.为什么方法中不能写静态变量 4. 解释一下ASCII码和ANSI码和两者的区别 5.简述j ava.io java.sql java.awt java.rmi 分别是什么类型的包 6. 看下面一段代码&#xff1a;…

Ubuntu安装RabbitMQ server - 在外远程访问

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

安装OpenSearch

title: “安装opensearch” createTime: 2021-11-30T19:13:4508:00 updateTime: 2021-11-30T19:13:4508:00 draft: false author: “name” tags: [“es”,“安装”] categories: [“OpenSearch”] description: “测试的” 说明 基于Elasticsearch7.10.2 的 opensearch-1.1.…

使用QLoRA对Llama 2进行微调的详细笔记

使用QLoRA对Llama 2进行微调是我们常用的一个方法&#xff0c;但是在微调时会遇到各种各样的问题&#xff0c;所以在本文中&#xff0c;将尝试以详细注释的方式给出一些常见问题的答案。这些问题是特定于代码的&#xff0c;大多数注释都是针对所涉及的开源库以及所使用的方法和…

高并发系统 - 接口幂等技术方案,高可用系统架构与技术选型

幂等概念来自于数学,在计算机科学中,幂等表示一次后、或多次请求某一资源,应该有同样的影响效果。 在业务表现上一般是同样的数据效果,下面就常用的业务场景,来聊聊幂等的技术方案。 ----------------- 数据层 ----------------- 索引与事务 根据业务需要,给表添加唯一索…

C++中执行shell命令,popen与system的区别

C中执行shell命令&#xff0c;popen与system的区别_c popen_Op_chaos的博客-CSDN博客 2.system system()函数执行过程&#xff1a; 1.fork一个子进程&#xff1b; 2.在子进程中调用exec函数去执行command&#xff1b; 3.在父进程中调用wait去等待子进程结束。 由于system没…

RHCE——二十一、Ansible模块

RHCE 一、Ansible的三个命令模块1、组成2、特点3、区别3.1 command、shell模块:3.2 raw模块 4、command模块4.1 参数表4.2 free_form参数 5、shell模块5.1 作用5.2 例25.3 script模块5.4 例3 6、raw模块6.1 参数6.2 例4 二、文件操作模块1、file 模块1.1 参数1.2 案例 2、copy …

【工作记录】springboot集成aop实现日志@20230918

springboot集成aop实现日志 1. 添加依赖 <!-- aop 依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency>2. 定义注解 Target(ElementType.METHOD)…

windows 安装 MySQL 绿色版

windows 安装 MySQL 绿色版 下载 官网&#xff1a; MySQL下载页面&#xff1a; MySQL直接下载链接&#xff1a;https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.34-winx64.zip 安装 将下载的mysql.zip文件解压缩到指定目录 搜索 cmd 并以管理员身份运行 切换到…

【微信小程序开发】宠物预约医疗项目实战-注册实现

【微信小程序开发】宠物预约医疗项目实战-注册实现 第二章 宠物预约医疗项目实战-注册实现 文章目录 【微信小程序开发】宠物预约医疗项目实战-注册实现前言一、打开项目文件二、编写wxss代码2.1 什么是wxss2.2 配置主程序全局样式 三. 在sign文件下的wxml文件中编写如下代码并…

数字森林:无人机航测技术在林业调查中的应用

林业调查是林业工作的基础&#xff0c;对于森林资源的管理、规划、保护、经济发展和农业种植等方面都具有重要的意义。传统林业调查主要依赖人工进行&#xff0c;存在工作效率低、数据精度低、数据分析困难、受地形限制、无法实时监测等缺陷。 随着科技的不断发展&#xff0c;无…

最新Python大数据之Excel进阶

文章目录 Excel图表类型了解有哪些图表类型 Excel图表使用图表的创建方式利用固定数据区域创建图表编辑数据系列添加数据标签格式化图表 Excel数据透视表数据透视表对原始数据的要求创建数据透视表数据透视表字段布局将数据透视图变成普通图表 Excel图表类型 为了揭示数据规律…

Open3D 进阶(11)使用GMM-Tree算法对点云配准

GMM-Tree算法 一、算法原理1、主要函数2、参考文献二、代码实现三、结果展示1、点云初始位置2、配准后的位置四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 一、算法原理 1、

Windows 10 + Jenkins 2.4 安装插件时https 的证书问题及解决

本篇面临与解决的问题 本篇是在 Windows 10中安装Jenkins 2.414.1 &#xff0c; 在安装完成之后安装一些需要的插件&#xff0c; 可以在浏览器端安装插件的时候&#xff0c; 总是不成功&#xff0c; 控制台报以下错误&#xff1a; SEVERE h.model.UpdateCenter$DownloadJob#r…

枚举连通块拆贡献+容斥:ABC312G

https://atcoder.jp/contests/abc321/tasks/abc321_g 这种题都没看出来我要去退役了 看完题目&#xff0c;可以获得&#xff1a; 期望、连通块&#xff1a;显然拆贡献啊&#xff01; n ≤ 17 n\le 17 n≤17&#xff1a;这不明显状压&#xff1f;结合前面连通块&#xff0c;就…