C++基本语言:1.10类型转换:static_cast等

news2024/11/15 12:57:41

C++基本语言包含10章节内容,存于C++从入门到精通专栏

目录

一、隐式类型转换

​编辑二、显式类型转换(强制类型转换)

(1)static_cast:静态转换

可用于

不可用于

(2)dynamic_cast

(3)const_cast

(4)reinterpret_cast

三、总结

一、隐式类型转换

一个double和一个int做加 法运算,那么int会转换成double,然后再和double做运算,这个类型转 换是系统自动进行的,不需要人为介入,所以这种转换叫隐式类型转换。

 但如果用一个整型变量保存这个结果,因为是整型变量,不能保存小数部分,所以系统会把小数部分舍弃,把整数部分赋予这个变量,这也可以看作隐式类型转换。看如下代码:

aa323f8ed5324b22a4d5a899e6f0f363.png

二、显式类型转换(强制类型转换)

显式类型转换,也叫强制类型转换。

8d99de18d92247c4aee3fb0c1380a416.png

上面这个属于C语言风格的强制类型转换——直接把类型用“()” 括起来。

没有类型方面的检查,直接硬转,转的是对还是错,程序员必须提供保障。

除了把类型用“()”括起来之外,其实,如果不括类型,括数字也可以,括数字也称为函数风格的强制类型转换(看起来有点像函数调用):

51752e90a735419faeec2aa5d22962ec.png

在C++中,强制类型转换分为4种。

当然,C语言中的强制类型转换依然支持,但这种支持只是为了语言兼容性的考虑。

C++中的4种强制类型转换分别用于不同的目的

这4种强制类型转换,每一种都有一个不同的名字,提供更丰富的含义和功能以及更好的类型检查机制,方便代码的书写和维护。

强制类型转换(强制类型转换运算符或者强制类型转换操作符):

(a)static_cast

(b)dynamic_cast

(c) const_cast

(d)reinterpret_cast

这4种 强制类型转换都被称呼为“命名的强制类型转换”(因为它们每一个都 名字而且名字都不同)。

看一下这些命名的强制类型转换的通用形式:

4d49b5df665b4ee19430a23800dbbb12.png

强制类型转换名就是static_cast、dynamic_cast、const_cast、 reinterpret_cast 这四个名字之一,用来指定是哪种转换;type是转换的目标类型;express是要转换的值(你要转换的是谁)

(1)static_cast:静态转换

者就理解成正常转换,属于编译的时候就会进行类型转换的检查。代码中要保证转换的安全性和正确性,与C语言中的强制类型转换的感觉差不多

一般的编译器能够执行的隐式的类型转换 以及 C风格的强制转换都可以用static_cast来显式完成。

可用于

 ①相关类型转换,如整型和实型之间的转换。

6ba4f9767626430ba293efadf4f6953f.png

②后续学习类的时候,子类转成父类类型(有继承关系)也能用 static_cast。

这里简单看一下代码:

a010031eb3e04a49804281d6ebd17989.png

③void*与其他类型指针之间的转换:void *是属于“无类型指针”(万能指针) ,也就是可以指向任何的指针类型。

aeae11a3b2154da3a83a9c9844f1f4fd.png

不可用于

一般不能用于指针类型之间的转换,如int *转double *、float *转 double*等。

当然,如果本身是double*,然后要转成double*还是可以的

操作:其实具体可不可以转可以先把代码写出来,看看编译器包不报错

af4e8d2dd5e74e50b0e01a363b907057.png

(2)dynamic_cast

(2)dynamic_cast:该转换应用在运行时类型识别和检查

(与 static_cast不一样,static_cast是编译时类型检查)方面

主要用来进行父类型转成子类型,后面章节(3.10)会详细讨论。但是因为要做类型检查,所以检查的代价很昂贵,但也保证了转换的安全性。

(3)const_cast

const_cast:去除 指针或者引用的const属性。

换句话说,这 个转换能够将const性质转换掉,这个类型转换只能做这件事(功能比较有限)。同样,也属于编译的时候就会进行类型转换的检查。

f435efe21d8549af8a07682ff15cdbf4.png

一个一开始有const属性的东西你不要往里面写值,虽然语法上没错;但是这种写值行为,是一种未定义行为。

*pai2=120;//这种写值行为 是属于一种未定义行为,大家不要这么干

所谓未定义(不确定行为):与可能写进去也有可能没写进去,还有可能编译的时候写进去了,但是打印的时候没写进去

其实上面的代码也可以写成类似的C语言风格

53b50f602d2c43baa0a6b11c5f1854d5.png

请注意,如果本来是一个常量,若强硬地用const_cast去掉了常量性质并往里面写值,这是一种未定义行为,不要这样做,以免产生无法预料的后果。

除非它原来不是常量,后来被变为常量,再后来又用const_cast 给它变回非常量,这个时候能往里写值

const_cast很特殊,只有这个转换能去掉表达式的常量属性,所以这 个转换的能力是其他类型转换运算符无法替代的。 另外,const_cast也不能改变表达式类型。

c06ccefa37a24825b4985997a270b11b.png

(4)reinterpret_cast

reinterpret_cast:也属于编译的时候就会进行类型转换的检查。

reinterpret:重新解释、重新解读的意思(将所操作的内容解释为另一种不同的类型)

用来处理无关类型的转换,也就是两个转换的类型之间没有什么关系,那就等于乱转、瞎 转、自由转的意思,就是怎么转都行,所以这个类型转换相当随意。

常用于如下两种转换:

 ①将一个整型(地址)转换成指针、一种类型指针转成另外一种类型指针,按照转换后的类型重新解释内存中的内容。

②可从一个指针类型到一个整型进行转换

ac1e7699f465477fa0ea157d0ec33ac5.png

这种转换本身不报错,但这个地址本身存的是int(比如10),却把它转成字符指针("\n"),虽然转换成功(语法上对),但要是当成字符指针用,肯定程序会出错。

 当然,转成void*再转换回来还是可以的

277cb15f1cc04a1a8dc11b0e86a8304b.png

笔者不建议读者轻易使用这个类型转换,这个类型转换被认为是一种危险的类型转换,似乎功能非常强大,类型之间任意转,编译器都不会报错,但从写程序的角度来讲,如果随便乱转显然没有意义,只会导致程序运行出错。所以这个类型转换安全性很差(只在一些很特殊的场合下会用)。但是以后在读他人代码时,看到这个类型转换可以观察观察别人是怎样使用的。看看如下范例:

long64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1

f23683e236964adf8e8a0fb687a90513.png

//因为int*是4字节的,没办法保存8字节的东西

三、总结

(1)强制类型转换一般不建议使用。因为会干扰系统的正常类型检查。很多异常转换本来编译器会报错的,但是一旦用了这些类型转换,就会抑制编译器的报错行为

(2)如果读者有兴趣,可以对这些类型转换做任意自己能想到的尝试,也许能够发现一些很诡异的内容或者有一些新发现也说不定。本节的主要目的还是带着读者先认识一下这些类型转换符,以免以后遇到它们时不知所措。

(3)有句话叫使用reinterpret_cast非常危险,而使用const_cast 总是意味着设计缺陷。笔者觉得尤其要注意后面这半句话——读者如果真用到const_cast,就要检查检查自己代码的设计问题了,因为平白无故地 利用const_cast去掉const属性是很让人费解的设计。

(4)如果实在需要用到类型转换,建议全部用本节讲解的新风格。一般的, static_cast和reinterpret_cast就能很好地取代C语言风格的类型转换。

reinterpret_cast只要好好用,合乎规则,就很好用

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

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

相关文章

.NET国产化改造探索(一)、VMware安装银河麒麟

随着时代的发展以及近年来信创工作和…废话就不多说了,这个系列就是为.NET遇到国产化需求的一个闭坑系列。接下来,看操作。 安装银河麒麟 麒麟系统分银河麒麟和中标麒麟,我选择的是银河麒麟服务器版的,关于如何下载,…

长沙竟然有这么多芯片公司!

从英特尔的持续裁员,美满团队撤出国内市场,再到哲库解散,星际魅族放弃芯片业务,再到年底摩尔等公司大裁员,TCL控股子公司摩星半导体解散,都让每个ICer对市场失去信心。 目前,长沙集成电路产业布…

C++ 实现Windows WIFI管理器

文章目录 前言一、代码二、补充知识三、遇到的问题字符集转换 四、剩余问题总结 前言 出于项目需要,需要用C开发一个wifi界面,实现wifi扫描、wifi连接与断开、wifi密码记住的基础功能。 一、代码 话不多说,直接上代码。 #pragma once #inc…

Godot4.2——爬虫小游戏简单制作

目录 一、项目 二、项目功能 怪物 人物 快捷键 分数 游戏说明 提示信息 三、学习视频 UI制作 游戏教程 四、总结 一、项目 视频演示:Godot4爬虫小游戏简单制作_哔哩哔哩bilibili 游戏教程:【小猫godot4入门教程 C#版 已完结】官方入门案例 第…

利用MATLAB绘制折线图

x20:20:140;%x轴上的数据,第一个值代表数据开始,第二个值代表间隔,第三个值代表终止a[0.85, 2.2, 3.45, 2.65, 1.5, 1.9, 1.25]; %a数据y值plot(x,a,-*b); %线性,颜色,标记 axis([0,160,0,4]) %确定x轴与y轴框图大小 …

Redis - 挖矿病毒 db0 库 backup 反复出现解决方案

问题描述 腾讯云的服务器,使用 Docker 部署了 Redis 之后,发现 DB0 中总是出现 4 条 key,分别是 backup01backup02backup03backup04 而自己每次存入 db0 中的数据过一会就会被无缘无故删除掉。 原因分析 挖矿病毒 解决方案 在启动的时候…

Android测试——(下篇)

Android测试(五):Instrumented 单元测试 Instrumented 单元测试是在真机并且可以上运行的测试,它利用Android框架API和支持的API(如Android测试支持库)。如果你的测试需要访问工具信息(例如目标…

基于果蝇算法优化的Elman神经网络数据预测 - 附代码

基于果蝇算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于果蝇算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于果蝇优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要:针…

Jmeter的安装与快速使用(做并发测试)

1、了解 JMeter是一款开源的性能测试工具,它主要用于模拟多种负载条件下的应用程序或服务器的性能和功能。JMeter可以发送不同类型的请求,如HTTP、HTTPS、FTP、SOAP、REST等,并且可以模拟多种负载类型,例如并发用户、线程组、定时…

洛谷普及组P1044栈,题目讲解(无数论基础,纯打表找规律)

[NOIP2003 普及组] 栈 - 洛谷 我先写了个打表的代码&#xff0c;写了一个小时&#xff0c;o(╥﹏╥)o只能说我真不擅长dfs。 int n; std::unordered_map<std::string, int>map; void dfs(std::vector<int>&a, int step,std::stack<int>p, std::string …

【K8S 资源管理】声明式资源管理

目录 一、常用的发布方式 1、蓝绿发布&#xff1a; 2、金丝雀发布&#xff08;灰度发布&#xff09;&#xff1a; 3、滚动更新&#xff08;deployment的默认更新方式&#xff09;&#xff1a; 二、声明式管理方法&#xff08;yaml文件&#xff09; 1、三种发布命令&#x…

C语言中灵活多变的动态内存,malloc函数 free函数 calloc函数 realloc函数

文章目录 &#x1f680;前言&#x1f680;管理动态内存的函数✈️malloc函数✈️free函数✈️calloc函数✈️realloc函数 &#x1f680;在使用动态内存函数时的常见错误✈️对NULL指针的解引用✈️ 对动态开辟空间的越界访问✈️对非动态开辟内存使用free释放✈️使用free释放一…

三、C语言中的分支与循环—for循环 (6)

本章分支结构的学习内容如下&#xff1a; 三、C语言中的分支与循环—if语句 (1) 三、C语言中的分支与循环—关系操作符 (2) 三、C语言中的分支与循环—条件操作符 与逻辑操作符(3) 三、C语言中的分支与循环—switch语句&#xff08;4&#xff09;分支结构 完 本章循环结构的…

【SpringBoot框架篇】34.使用Spring Retry完成任务的重试

文章目录 简要1.为什么需要重试&#xff1f;2.添加maven依赖3.使用Retryable注解实现重试4.基于RetryTemplate模板实现重试 简要 Spring实现了一套重试机制&#xff0c;功能简单实用。Spring Retry是从Spring Batch独立出来的一个功能&#xff0c;已经广泛应用于Spring Batch,…

Linux 进程和计划任务管理

一 内核功用&#xff1a;进程管理、内存管理、文件系统、网络功能、驱动程序、安全功能等 1 程序 是一组计算机能识别和执行的指令&#xff0c;运行于电子计算机上&#xff0c;满足人们某种需求的信息化工具 用于描述进程要完成的功能&#xff0c;是控制进程执行的指令集 2…

LeetCode 82:删除排序链表中的重复元素 II

一、题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,3,4,4,5] 输出&#xff1a;[1,2,5]示例 2&#xff1a; 输入&#xff1a…

B01、类加载子系统-02

JVM架构图-英文版 中文版见下图&#xff1a; 1、概述类的加载器及类加载过程 1.1、类加载子系统的作用 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engi…

炫酷按钮制作(HTML+CSS+Javascript)

实现效果&#xff1a; 当鼠标点击按钮时&#xff1a; 实现代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>div{margin-top: 20px;margin-left: 20px;}.button{border: soli…

力扣热题100道-矩阵篇

矩阵 73.矩阵置零 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法**。** 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]]示例…

CSS 顶部位置翻转动画

<template><div class"container" mouseenter"startAnimation" mouseleave"stopAnimation"><!-- 旋方块 --><div class"box" :class"{ rotate-hor-top: isAnimating }"><!-- 元素内容 --><…