《C++的类型转换》

目录

一、c语言中的类型转换

1、隐式类型转化:

2、强制类型转化:

3、缺点

二、c++新的类型转换

1、内置类型转为自定义类型

3、自定义类型转换为内置类型

三、C++的规范的强制类型转换

1、C++新增四种规范的类型转换的原因

2、static_cast

3、reinterpret_cast

4、const_cast

5、dynamic_cast

6、警惕强制转化

结束语


前言

        本篇文章来介绍C++11基于C语言对于类型转换变化的介绍,介绍类型转换的新增内容,内容干货满满,看这一篇包学会

一、c语言中的类型转换

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

1、隐式类型转化:

        编译器在编译阶段自动进行,能转就转,不能转就编译失败。

        通常发生在整形之间,整形和浮点数之间。bool和整形之间, bool和指针之间(利用指针是否为空指针做判断时存在隐式转换),如下图举例

其他场景介绍:

        下图比较的时候end会隐式类型转换成size_t,再比较

2、强制类型转化:

        一般用于指针转换,需要用户自己处理,显示的转换类型如下图(存在截断风险)所示

特别注意只有类型之间有一定关联的时候才会发生类型转换,毫不相干的两个类型不能发生转换

如下图所示,无法将一个指针转换为double类型变量:

3、缺点

        转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换


二、c++新的类型转换

        c++是面向对象的语言,c++语言带来了自定义类型的对象,为类型的家族注入新鲜新鲜血液的同时,也带来了内置类型与自定义类型之间互相转换的问题

1、内置类型转为自定义类型

        定义类的时增添对应参数的构造,直接调用构造对象,内置类型作为传参构造为对应的自定义类型的对象。

2、自定义类型转换为自定义类型

        对于这种转换,我们也是只需要定义类的时增添对应参数的构造就可以实现对应的类型转化(调用参数与被转换类型匹配的构造函数)。

        联系到STL库中,某一个容器可以使用{ }进行多个元素初始化的原理,就实现了自定义类型及内置类型向自定义类型的一个转换,{ }中的多个内置类型,先转换为多个容器中的单位元素类型(内置类型转自定义类型对象);所有转换过来的的元素构造为initializer_list对象,最终利用initializer_list转换为对应的容器类型对象(构造函数支持自定义转自定义类型对象)。具体的原理实现大家可以参考博客《C++11实用方法介绍(一)》中的讲解,更深层次的理解。

特别注意:

        在继承与多态当中,基类对象可以赋值给基类变量,好像是两个自定义类型之间的转换,但这不是类型转化,这是切片操作,这万万不可混为一谈!!!

3、自定义类型转换为内置类型

        这种情况看起来很奇怪,内置类型可以转换为自定义类型是因为有对应的构造函数支持,而内置类型都是写好的,我们无法为其增添支持操作的构造函数,拿又该怎么办呢?

        本质要重载一个operator类型 隐式类型转换 如:下面的A

        由于隐式转换(C语言的沉重历史包袱)的存在,迫于无奈只能特殊处理,operator +类型,不需要有返回值


三、C++的规范的强制类型转换

1、C++新增四种规范的类型转换的原因

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

        1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失

        2. 显式类型转换将所有情况混合在一起,代码不够清晰

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

即非必须实用C++11规范化类型转换(保证以前的代码仍然可以用),但最好是规范!!!(很多大型公司强制要求,要有好的代码编写习惯)

2、static_cast<T>

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

等同于以前的隐式类型转换

下图为使用举例(double->int)

3、reinterpret_cast<T>

        通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型

        等同于以前的强制类型转换(有一方为指针转换)

        下图为使用举例(int->int*)

4、const_cast<T>

        最常用的用途就是删除变量的const属性,方便赋值

Q:这也是强制类型转换,但是为什么要把去掉const属性单独拿出来做一个类型转换操作符?

(1)原来去除const类型的方式

        我们预估a1的值已经被改变为3,可是结果表示并没有更改,结果与预想并不对应。难道真的是我们的a1数值没有改变吗?让我们来看一下监视窗口:

        我们发现此时a1的数值确实被改为了3,但为什么仍然直接打印a1时会不对。这个时候我们就要补充一些知识:编译器看到const类型的变量,会将变量扔到寄存器(增加访问效率),我们这里更改其数值,更改的是它在内存中存储的数值,寄存器中的没有改动,输出时输出的是寄存器中没有改动过的变量。故而这里出现错误。

        去掉const属性是有一些内存可见优化的的风险,通过在定义const变量前添加volatile修饰符,表明此数据不存入寄存器来解决。

2、使用关键字规范化去除

        这里就是专门提醒去掉const属性是有一些内存可见优化的的风险,要注意是否加了volatile,这也回答了上面提出的问题

5、dynamic_cast<T>

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

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

向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)

我们给定一个基类,一个子类,以及参数为基类指针的函数(举例):

由于函数参数为基类的指针,它既可以指向基类对象,也可以指向子类对象

(1)、pa指向子类对象,转回子类,是安全的,正常转换

(2)、pa指向父类对象(基类可能没有子类新加的成员),转回子类,是不安全的,存在越界的风险问题,转换失败

利用dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回

注意:

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

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

6、警惕强制转化

        强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换!!!!


结束语

        本篇文章的内容就到此结束了,对于c++11的类型转化的介绍也来到尾声,希望大家能有所收获,能够应用自如,如果有什么内容不明白的,大家可以在评论去向我提问,我会一一回答,当然有什么错误或者有什么不足的地方,希望大家可以包容并指出。希望大家可以持续关注之后内容,最后向每一位读者送上真诚的小花。

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

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

相关文章

PotatoPie 4.0 实验教程(29) —— FPGA实现摄像头图像均值滤波处理

图像的均值滤波简介 图像均值滤波处理是一种常见的图像处理技术&#xff0c;用于降低图像中噪声的影响并平滑图像。该方法通过在图像中滑动一个固定大小的窗口&#xff08;通常是一个正方形或矩形&#xff09;&#xff0c;将窗口中所有像素的值取平均来计算窗口中心像素的新值…

【Android】SharedPreferences阻塞问题深度分析

前言 Android中SharedPreferences已经广为诟病&#xff0c;它虽然是Android SDK中自带的数据存储API&#xff0c;但是因为存在设计上的缺陷&#xff0c;在处理大量数据时很容易导致UI线程阻塞或者ANR&#xff0c;Android官方最终在Jetpack库中提供了DataStore解决方案&#xf…

数据结构——插入排序

基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。 实际中我们玩扑克牌时&…

1146. 快照数组

java版本 class SnapshotArray {int id 0;List<int[]>[] snapshots;public SnapshotArray(int length) {snapshots new List[length];for (int i 0; i < length; i) {snapshots[i] new ArrayList<int[]>();}}public void set(int index, int val) {snapsho…

XYCTF-部分web总结

这个月在XYCTF中写了部分web题&#xff0c;题中学到在此记录一下 ezhttp 打开就是一个简单的登录页面 f12说藏在一个地方&#xff0c;先想到的就是robots.txt 访问直接给账号密码 username: XYCTF password: JOILha!wuigqi123$登录后: 明显考源跳转&#xff0c;修改referer值…

如何查看 UUID 是那个版本

UUID 是有多个版本的&#xff0c;如何查看 UUID 是那个版本&#xff0c;可以用 UUID 对象中的 version() 方法。 创建 UUID 对象&#xff1a; UID originalUUID UUID.fromString("cc5f93f7-8cf1-4a51-83c6-e740313a0c6c"); uuid.version();上面方法显示 UUID 的版本…

通用模型Medprompt如何在医学领域超越专家系统

在AI的发展历程中&#xff0c;一直存在着两种理念的较量&#xff1a;一种是追求普适性的通用AI模型&#xff0c;另一种是针对特定领域深度优化的专业AI系统。最近&#xff0c;微软的研究团队在这一辩论中投下了一枚重磅炸弹——他们开发的Medprompt策略&#xff0c;使得通用AI模…

Gin框架入门(四)—中间件

文档 官方文档&#xff1a;https://godoc.org/github.com/gin-gonic/gin 官方地址&#xff1a;https://github.com/gin-gonic/gin 中间件&#xff1a;https://gin-gonic.com/zh-cn/docs/examples/using-middleware 无中间件 func main() {//创建一个无中间件路由r : gin.New…

前端用a标签实现静态资源文件(excel/word/pdf)下载

接上文实现的 前端实现将二进制文件流&#xff0c;并下载为excel文件后&#xff0c; 实际项目中一般都会有一个模版下载的功能&#xff0c;一般都由服务端提供一个下载接口&#xff0c;返回文件流或url地址&#xff0c;然后前端再处理成对应需要的类型的文件。 但是&#xff…

本地CPU搭建知识库大模型来体验学习Prompt Engineering/RAG/Agent/Text2sql

目录 1.环境 2.效果 3.概念解析 4.架构图 5. AI畅想 6.涉及到的技术方案 7. db-gpt的提示词 1.环境 基于一台16c 32G的纯CPU的机器来搭建 纯docker 打造 2.效果 3.概念解析 Prompt Engineering &#xff1a; 提示词工程 RAG&#xff1a; 检索增强生成&#xff1b; …

【源码】IM即时通讯源码/H5聊天软件/视频通话+语音通话/带文字部署教程

【源码介绍】 IM即时通讯源码/H5聊天软件/视频通话语音通话/带文字部署教程 【源码说明】 测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.2、MySQL5.6&#xff0c;根目录public&#xff0c;伪静态laravel5&#xff0c;根据情况开启SSL 登录后台看到很熟悉。。原来是…

el-table-column 表格列自适应宽度的组件封装说明

针对组件业务上的需求&#xff0c;需要给 el-table-column 加上限制&#xff0c;需保证表头在一行展示&#xff0c;部分列的内容要一行展示&#xff0c;自适应单项列的宽度&#xff1b; 1、先计算数据渲染后的 el-table-column 文本宽度&#xff1b; 因列表的有些数据需要做到…

如此建立网络根文件系统 Mount NFS RootFS

安静NFS系统服务 sudo apt-get install nfs-kernel-server 创建目录 sudo mkdir /rootfsLee 将buildroot编译的根文件系统解压缩到 sudo tar xvf rootfs.tar -C /rootfsLee/ 添加文件NFS访问路径 sudo vi /etc/exports sudo /etc/exports文件&#xff0c;添加如下一行 …

网站推荐——文本对比工具

在线文字对比工具-BeJSON.com 文本对比/字符串差异比较 - 在线工具 在线文本对比-文本内容差异比较-校对专用

企业智能名片小程序:AI智能跟进功能助力精准营销新篇章

在数字化浪潮的推动下&#xff0c;企业营销手段不断迭代升级。如今&#xff0c;一款集手机号授权自动获取、智能提醒、访客AI智能跟进及客户画像与行为记录于一体的企业智能名片小程序&#xff0c;正以其强大的AI智能跟进功能&#xff0c;助力企业开启精准营销的新篇章。 通过深…

图像处理到神经网络:线性代数的跨领域应用探索

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作 作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打怪升级之旅 python数据分析…

Swift 中的 Range 运算符

在 Swift 中&#xff0c;Range 运算符是一种强大的工具&#xff0c;用于表示一系列连续的数值或字符。Range 可以用于循环、数组切片、条件语句等场景&#xff0c;为我们提供了方便的方法来处理数据集合。 闭区间运算符 a...b 闭区间运算符 a...b 用于创建一个从起始值到结束…

无监督学习的评价指标

轮廓系数&#xff08;Silhouette Coefficient&#xff09; 轮廓系数用于判断聚类结果的紧密度和分离度。轮廓系数综合了样本与其所属簇内的相似度以及最近的其他簇间的不相似度。 其计算方法如下&#xff1a; 1、计算簇中的每个样本i 1.计算a&#xff08;i&#xff09; &#x…

百度SDK创建应用地址解析失败问题

在百度SDK的设置里先用IP白名单校验全部都通过&#xff0c;项目上线之后再改就行 0.0.0.0/0

【Leetcode每日一题】 分治 - 面试题 17.14. 最小K个数(难度⭐⭐)(66)

1. 题目解析 题目链接&#xff1a;面试题 17.14. 最小K个数 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 在快速排序算法中&#xff0c;我们通常会通过选择一个基准元素&#xff0c;然后将数组划分为三个部分&…