04 C++中的四种强制类型转换
系列文章目录
04 C++中的四种强制类型转换
目录
系列文章目录
文章目录
前言
一、静态转换(Static Cast)
二、动态转换(Dynamic Cast)
三、常量转换(Const Cast)
四、重新解释转换(Reinterpret Cast)
总结
前言
类型转换是将一个数据类型的值转换为另一种数据类型的值。
C++ 中有四种类型转换:静态转换、动态转换、常量转换和重新解释转换。
隐式类型转换是编译器自动隐式进行的,需要在代码中体现,而显示类型转换由程序员明确指定。
C++支持C风格的强制转换,但是C风格的强制转换可能带来一些隐患,让一些问题难以发现。
所以C++提供了一组适用于不同场景的强制转换的函数:
- static_cast
- dynamic_cast
- const_cast
- reinterpret_cast
下面对这四种转换操作的适用场景分别进行说明。
一、静态转换(Static Cast)
静态转换是将一种数据类型的值强制转换为另一种数据类型的值。
静态转换通常用于比较类型相似的对象之间的转换,例如将 int 类型转换为 float 类型。
静态转换不进行任何运行时类型检查,因此可能会导致运行时错误。
下面是一个例子,将int类型转换为float类型:
int main()
{int a = 10;float b = static_cast<float>(a); // 静态将int类型转换为float类型cout << typeid (a).name() << endl;cout << typeid (b).name() << endl;}
输出结果为:
int
float
需要注意的是,这里,即使我们写int a = 'a';程序也可以编译过去,所以我们要注意使用。
二、动态转换(Dynamic Cast)
C++中的动态转换(dynamic_cast)是一种类型转换运算符,用于在运行时将指向父类的指针或引用转换为指向其派生类的指针或引用。
使用动态转换时,必须满足以下两个条件之一:
- 目标类型是源类型的公共派生类。
- 源类型是指向目标类型的指针或引用。
如果以上条件不满足,则转换将失败并返回空指针或引用。
下面是一个示例:
#include <iostream>
using namespace std;class Animal {
public:virtual void makeSound() {cout << "Unknown animal sound." << endl;}
};class Cat : public Animal {
public:void makeSound() {cout << "Meow!" << endl;}
};class Dog : public Animal {
public:void makeSound() {cout << "Woof!" << endl;}
};int main() {// 两个指针变量 a 和 b 分别指向一个 Cat 类型对象和一个 Dog 类型对象。Animal* a = new Cat;Animal* b = new Dog;// 使用动态类型转换将指针 a 转换为指向 Cat 类型的指针 c。Cat* c = dynamic_cast<Cat*>(a);// 判断指针 c 是否为 nullptr,如果不是,则调用 Cat 类的成员函数 makeSound() 输出动物的叫声;// 否则输出 “Cannot convert Animal* to Cat*.”。if (c) {c->makeSound();}else {cout << "Cannot convert Animal* to Cat*." << endl;}// 使用动态类型转换将指针 b 转换为指向 Cat 类型的指针 c。c = dynamic_cast<Cat*>(b);if (c) {c->makeSound();}else {cout << "Cannot convert Animal* to Cat*." << endl;}return 0;
}
输出结果为:
Meow!
Cannot convert Animal* to Cat*.
在此示例中,我们创建了两个Animal类型的指针,一个指向Cat对象,另一个指向Dog对象。接下来,我们使用Dynamic Cast将这些指针转换为指向Cat对象的指针。第一个转换将成功,因为指针a指向的是Cat对象。第二个转换失败,因为指针b指向的是Dog对象,无法转换为Cat对象。
注意:动态转换在代码中经常用于将基类对象转换为派生类对象,以便使用派生类的成员函数和成员变量。需要注意的是,使用动态转换时应该注意类型安全,并避免滥用。
三、常量转换(Const Cast)
常量转换用于将 const 类型的对象转换为非 const 类型的对象。
常量转换只能用于转换掉 const 属性,不能改变对象的类型
下面是一个常量转换(const_cast)的代码示例:
#include <iostream>
using namespace std;void printValue(int value) {cout << "The value is: " << value << endl;
}int main() {const int value = 10;const int* ptr = &value;// 将 ptr 转换为非常量指针int* mutablePtr = const_cast<int*>(ptr);// 修改指针所指向的值*mutablePtr = 20;// 调用函数输出修改后的值printValue(value);return 0;
}
在这个示例中,我们首先定义了一个常量值 value
和一个指向该值的常量指针 ptr
。然后,我们使用 const_cast
将 ptr
转换为非常量指针 mutablePtr
。接着,我们通过 mutablePtr
修改了指针所指向的值为 20
。最后,我们调用函数 printValue
输出修改后的值,即 20
。
需要注意的是,这里的常量指针指向的值并没有真正变为可修改的,只是通过 const_cast
绕过了编译器的常量性检查。因此,使用 const_cast
必须非常小心,避免对常量值进行意外的修改。
四、重新解释转换(Reinterpret Cast)
C++中的重新解释转换(Reinterpret Cast)是一种类型转换操作,用于将一个指针或引用转换为另一种不同类型的指针或引用,而不考虑它的原始类型和值。它主要用于将一个对象的位模式重新解释为另一个对象的位模式。由于这种类型转换没有进行类型检查,因此使用起来比较危险,应该谨慎使用。
以下是一个重新解释转换(reinterpret_cast)的代码:
#include <iostream>
using namespace std;int main() {int num = 100;double* pDouble = reinterpret_cast<double*>(&num);cout << "num = " << num << endl;cout << "pDouble = " << *pDouble << endl;return 0;
}
在这个例子中,我们将一个整数类型的变量num的地址,强制类型转换为了双精度浮点数类型的指针。这个强制类型转换的意义是告诉编译器将num的二进制数据按照双精度浮点数类型的格式重新解释。
当我们输出pDouble的值时,由于在编译器中整数和浮点数的存储方式一般是不同的,因此pDouble的值很可能会是随机垃圾数据。
因此,我们在实际开发中很少使用reinterpret_cast,除非我们确实需要进行一些非常特殊的操作。
总结
综上,在使用强制类型转换时,需要首先考虑清楚使用目的:
- static_cast:基本类型转换,低风险;
- dynamic_cast:类层次间的上行转换或下行转换,低风险;
- const_cast:去 const 属性,低风险;
- reinterpret_cast:转换不相关的类型,高风险。
相关文章:
04 C++中的四种强制类型转换
系列文章目录 04 C中的四种强制类型转换 目录 系列文章目录 文章目录 前言 一、静态转换(Static Cast) 二、动态转换(Dynamic Cast) 三、常量转换(Const Cast) 四、重新解释转换(Reinte…...
电力感知边缘计算网关产品设计方案-边缘计算自控算法模型
边缘计算网关与其他数据采集的IoT网关设备不同之处在于可以根据应用场景和产品解决方案,单独设置一些边缘计算算法模型,实现离线系统和边缘计算自控逻辑判别+执行系统方案,自控算法逻辑单元也是边缘计算网关自控系统方案的核心单元。 自控算法逻辑单元根据产品应用不同,有…...

C语言进阶之笔试题详解(1)
引言: 对指针知识进行简单的回顾,然后再完成笔试题。 ✨ 猪巴戒:个人主页✨ 所属专栏:《C语言进阶》 🎈跟着猪巴戒,一起学习C语言🎈 目录 引言: 知识简单回顾 指针是什么 指针变…...
报道|2023 INFORMS 最佳论文(部分)华人获奖者名单
编者按 本文收集了部分2023年INFORMS年会最佳论文评选的华人获奖者名单,祝贺获奖者们!如果读者身边有本文遗漏的获奖者请在文章下方评论区告诉小编。 ● George Nicholson学生论文竞赛一等奖: Bayesian Design Principles for Frequentist …...

【Docker】从零开始:12.容器数据卷
【Docker】从零开始:12.容器数据卷 1.什么是容器数据库卷2.数据的覆盖问题3.为什么要用数据卷4.Docker提供了两种卷:5.两种卷的区别6.bind mount7.Docker managed volumevolume 语法volume 操作参数 1.什么是容器数据库卷 卷 就是目录或文件,…...

Spring Boot 整合MyBatis-Plus 详解
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 全新的 MyBatis-Plus 3.0 版本基于 JDK8,提供了 lambda 形…...

【前端】让列表像Excel单元格一样编辑
前言 领导说了一堆的话,最后总结一句就是客户很懒,客户的员工更加懒。 本着让别人节省时间的原则,提倡出了让列表和Excal的单元格一样,不仅看数据还可以随时更改数据。 查资料 根据 Jeecg-Vue3 源码介绍,从而知道是基于 Vben Admin 开源项目进行改造的。 因此在 Vben…...

数字图像处理-Matlab实验
实验一 图像增强 实验内容: 对于给定的低对比度测试图像,利用灰度图像直方图均衡化算法进行图像视觉效果增强。 对于给定的低照度彩色测试图像,结合颜色空间转换和灰度图像直方图均衡化算法进行图像视觉效果增强。 实验数据: Test1_1.jpg: Test1_2.jpg: 实验步骤: %% …...

Nginx:配置文件详解
一、Nginx配置文件 main配置段:全局配置 events段:定义event工作模式 http {}:定义http协议配置 支持使用变量: 内置变量:模块会提供内建变脸定义 自定义变量:set var_name value 二、 主…...
卷积,是什么?
其实就是对事物的作用,或者说作用力,比如说,石板上没有字,我们刻上字,便于识别,从机器视觉角度来说,就是对图像的作用力,这种作用使得能看清想要的东西,感觉还是很主观&a…...
Javascript的闭包有哪些应用?
JavaScript 中的闭包是一种强大的特性,它可以用于多种应用。以下是一些闭包在 JavaScript 中的常见应用: 1、封装私有变量: 通过闭包,可以创建私有变量和方法。外部作用域无法直接访问闭包内的变量,从而实现了信息隐藏…...

LCM-LoRA模型推理简明教程
潜在一致性模型 (LCM) 通常可以通过 2-4 个步骤生成高质量图像,从而可以在几乎实时的设置中使用扩散模型。 来自官方网站: LCM 只需 4,000 个训练步骤(约 32 个 A100 GPU 小时)即可从任何预训练的稳定扩散 (SD) 中提取出来&#…...
设计模式-开篇
什么是设计模式 设计模式是一种被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、提高代码的可靠性。设计模式不是可直接转化为代码的完成解决方案,而是描述了如何解决一个问题的经过…...

HashMap的实现原;HashMap的工作原理;HashMap存储结构; HashMap 构造函数
文章目录 说一下HashMap的实现原理(非常重要)①HashMap的工作原理HashMap存储结构常用的变量HashMap 构造函数tableSizeFor() put()方法详解hash()计算原理resize() 扩容机制get()方法为什么HashMap链表会形成死循环 HashMap是我们在工作中使用到存储数据特别频繁的数据结构&am…...
JavaScript 原型,原型链的特点
JavaScript 的原型(Prototype)和原型链(Prototype chain)是 JavaScript 面向对象编程中的重要概念。 原型(Prototype) 在 JavaScript 中,每个对象都有一个原型对象,而这个原型对象…...

越南服务器租用:企业在越南办工厂的趋势与当地(ERP/OA等)系统部署的重要性
近年来,越南逐渐成为全球企业布局的热门目的地之一。许多企业纷纷选择在越南设立工厂,以利用其低廉的劳动力成本和优越的地理位置。随着企业在越南的扩张,对于当地部署ERP系统或OA系统等的需求也日益增长。在这种情况下,租用越南服…...
Qt QString与QChar总结
(一) QString 1 QString的简介 QString 是Qt 中的一个类,用于存储字符串,QString 没有父类。QString 存储的是一串字符,每个字符是一个 QChar 类型的数据。QChar 使用的是 UTF-16 编码,一个字符包含 2字节数据。 对于超过 6553…...

Leetcode算法系列| 1. 两数之和(四种解法)
目录 1.题目2.题解解法一:暴力枚举解法二:哈希表解法解法三:双指针(有序状态)解法四:二分查找(有序状态) 1.题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数…...

汇编-pop出栈指令
32位汇编 执行动作分为两步: 第一步:读出数据 第二步:改变栈地址 如果操作数是16位, 则ESP加2; 如果操作数是32位, 则ESP加4 espesp2 或 espesp4 格式:...

【代码】基于VMD(变分模态分解)-SSA(麻雀搜索算法优化)-LSTM的光伏功率预测模型(完美复现)matlab代码
程序名称:基于VMD(变分模态分解)-SSA(麻雀搜索算法优化)-LSTM的光伏功率预测模型 实现平台:matlab 代码简介:提出了变分模态分解(VMD)和麻雀搜索算法(SSA)与长短期记忆神经网络 (LSTM)相耦合,…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...