【C++】类型转换
目录
- 前言
- 一、C语言中的类型转换
- 二、为什么C++需要四种类型转换
- 三、C++强制类型转换
- 3.1 static_cast
- 3.2 reinterpret_cast
- 3.3 const_cast
- 3.4 dynamic_cast
- 3.5 RTTI
前言
本篇文章讲解的是C++中对于C语言类型转换做出的一些更好的规范问题,同时也保证了在一些特殊场景下进行类型转换的安全问题,下面就让我们一起来学习吧!!
一、C语言中的类型转换
在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。
- 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败。
- 显式类型转化:需要用户自己处理。
- 隐式类型转化是针对意义相近的类型,而显示的强制类型转换是针对意义不相近的类型,值转换后需要有意义。
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++ 为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:static_cast、reinterpret_cast、const_cast 和 dynamic_cast。
3.1 static_cast
static_cast 用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用 static_cast,但它不能用于两个不相关的类型进行转换。
int main()
{double d = 12.34;int a = static_cast<int>(d); // 相近类型之间的转换cout << a << endl;int* p = &a;//int address = static_cast<int>(p); // static_cast不能用于意义不相近的类型return 0;
}
3.2 reinterpret_cast
reinterpret_cast 操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。
int main()
{double d = 12.34;int a = static_cast<int>(d);cout << a << endl;// 这里使用static_cast会报错,应该使用reinterpret_cast//int *p = static_cast<int*>(a);int* p = reinterpret_cast<int*>(a);return 0;
}
3.3 const_cast
const_cast 最常用的用途就是删除变量的 const 属性,方便赋值,其对应的是 C 语言的强制类型转换。
int main()
{const int a = 2;//int* p = reinterpret_cast<int*>(&a); // 编译报错int* p = const_cast<int*>(&a);*p = 3;cout << a << endl; // 2cout << *p << endl; // 3cout << &a << endl;cout << p << endl;return 0;
}
为什么上图的地址一样,数据却不一样呢?这是由于const 修饰的变量,编译器认为其不会被修改,为了提高效率将其加载到寄存器中,所以第一个打印的 2 是在寄存器中取的,而第二个打印的 3 是在去内存中取的。
如果我们想要编译器不进行优化,而是每次取数据都去内存中取的话,此时可以加上volatile
关键字修饰const 变量 a,这样它就不会被加载到寄存器中了。
3.4 dynamic_cast
dynamic_cast 用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)。
向上转化:子类对象指针 / 引用转换成父类指针 / 引用,不需要转换,赋值兼容规则。
向下转型:父类对象指针 / 引用转换成子类指针 / 引用需要使用 dynamic_cast,dynamic_cast 转换是安全的。(注:对象是不能转换的!父类对象转子类对象就拥有了子类对象的属性了??绝对不能的!)
注意:
1. dynamic_cast 只能用于父类含有虚函数的类(本身设计出来就是为了处理多态场景中的类型转换问题)。
2. dynamic_cast 会先检查是否能转换成功,能成功转换则返回正确的地址,不能则返回 nullptr。
我们先来分析一下这段程序:
class A
{
public:virtual void f() {}int _a = 0;
};class B : public A
{
public:int _b = 1;
};void fun(A* pa)
{B* pb1 = (B*)pa;cout << "pb1:" << pb1 << endl;pb1->_a++;pb1->_b++;cout << pb1->_a << " : " << pb1->_b << endl;
}int main()
{A a;B b;fun(&a);fun(&b);return 0;
}
为何当父类指针指向父类对象时,强转为指向子类对象访问子类对象的成员会崩溃呢?
所以为了避免这种情况的发生,我们设计出了dynamic_cast来解决这个问题:
强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换。
3.5 RTTI
RTTI:Run-time Type identification的简称,即:运行时类型识别。
C++通过以下方式来支持RTTI:
- typeid运算符(可以拿到变量对应类型的字符串)
- dynamic_cast运算符(可以识别父类的指针是指向父类对象还是子类对象)
- decltype(可以推导一个对象的类型,并用该类型来定义对象。)
相关文章:

【C++】类型转换
目录 前言一、C语言中的类型转换二、为什么C需要四种类型转换三、C强制类型转换3.1 static_cast3.2 reinterpret_cast3.3 const_cast3.4 dynamic_cast3.5 RTTI 前言 本篇文章讲解的是C中对于C语言类型转换做出的一些更好的规范问题,同时也保证了在一些特殊场景下进…...
Redis RDB 持久化问题
前言 Redis 是内存数据库,它将自己的数据储存在内存里面,如果不想办法将储存在内存中的数据保存到磁盘里面,那么一旦服务器进程退出,服务器中的数据也就没了。 因此,Redis 提供了 RDB 持久化功能,这个功能…...
windows 下nginx常用命令
1、启动,目录cmd,后 start nginx.exe 2.重新加载 nginx -s reload 3.查看状态 tasklist /fi “imagename eq nginx.exe” 4.关闭 nginx -s quit...
xjoi题库一级1-10段题解(c语言版)
xjoi题库一级一段 xjoi题库一级二段 xjoi题库一级三段 xjoi题库一级四段 xjoi题库一级五段...

1.int 与 Integer 的简单区别
蓝桥杯刷题从此开始: 第一题就是两个数的和,个人看来主要考察 int与integer 的区别; 这是我提交的答案,竟然会报错: import java.util.*; //输入A、B,输出AB。 class add {public static void main(String …...

单片机原理及技术(二)—— AT89S51单片机(一)(C51编程)
目录 一、AT89S51单片机的片内硬件结构 二、AT89S51的引脚功能 2.1 电源及时钟引脚 2.2 控制引脚 2.3 并行 I/O口引脚 三、AT89S51的CPU 3.1 运算器 3.1.1 算术逻辑单元(ALU) 3.1.2 累加器A 3.1.3 程序状态字寄存器(PSW)…...

某方protobuf闲谈
问题 当我们去看某方的时候,搜索了关键词svm,然后通过抓包查看,请求的Request Payload是一串看不懂的乱码,并且返回的数据也大部分是乱码 观察请求的Content-Type是application/grpc-web+proto,没错数据的传输是protobuf的形式了 protobuf的相关概念和原理,网上有很多教…...

专为汽车内容打造的智能剪辑解决方案
汽车内容创作已成为越来越多车主和汽车爱好者热衷的活动。然而,如何高效、便捷地将行车途中的精彩瞬间转化为高质量的视频作品,一直是困扰着广大用户的一大难题。美摄科技凭借其深厚的视频处理技术和智能分析能力,推出了专为汽车内容记录而生…...

【C语言】二叉树的实现
文章目录 前言⭐一、二叉树的定义🚲二、创建二叉树🎡三、二叉树的销毁🎉四、遍历二叉树1. 前序遍历2. 中序遍历3. 后序遍历4. 层序遍历 🌲五、二叉树的计算1. 计算二叉树结点个数2. 计算二叉树叶子结点的个数3. 计算二叉树的深度4…...

在ubuntu22.04里网站源码连不上mysql数据库
在ubuntu22.04里网站源码连不上mysql数据库。后来找到了原因。 连不上的时候有报错信息: ERROR 1698 (28000): Access denied for user rootlocalhost 用在网上搜索该报错信息,找到了两篇有用的文章,用这两篇文章里的处理方法解决了问题。 …...

博客说明 5/12~5/24【个人】
博客说明 5/12~5/24【个人】 前言版权博客说明 5/12~5/24【个人】对比最后 前言 2024-5-24 13:39:23 对我在2024年5月12日到5月24日发布的博客做一下简要的说明 以下内容源自《【个人】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作…...
豆瓣电影后端设计
sql脚本 -- douban.tags_encode definitionCREATE TABLE tags_encode (id bigint NOT NULL AUTO_INCREMENT COMMENT 自增主键,tag varchar(100) NOT NULL COMMENT tag中文名,tag_encode varchar(100) NOT NULL COMMENT tag转encode,type varchar(100) NOT NULL DEFAULT movie …...

【深度学习】第1章
概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…...

Vue3实战笔记(37)—粒子特效登录页面
文章目录 前言一、粒子特效登录页总结 前言 上头了,再来一个粒子特效登录页面。 一、粒子特效登录页 登录页: <template><div><vue-particles id"tsparticles" particles-loaded"particlesLoaded" :options"…...
解锁无限可能:JavaScript与【机器学习】的浪漫邂逅
解锁无限可能:JavaScript与机器学习的浪漫邂逅 在人工智能和大数据日益盛行的今天,机器学习已成为我们理解、分析和处理数据的强大工具。而JavaScript,作为前端开发的主流语言,其灵活的特性和广泛的应用场景也让我们对其充满了期…...
【Linux】$()中的内容与不加$()时有什么区别
$()中的内容与不加$()有什么区别,例如$(/usr/local/hadoop/bin/hadoop classpath)与/usr/local/hadoop/bin/hadoop classpath两者有何区别??? 关于这个问题,笔者建议可以参考如下文章: Linux—shell中$((…...

2024最新前端面试八股文【基础篇293题】
⼀、HTML、HTTP、web综合问题 1 前端需要注意哪些SEO 2 <img> 的 title 和 alt 有什么区别 3 HTTP的⼏种请求⽅法⽤途 4 从浏览器地址栏输⼊url到显示⻚⾯的步骤 5 如何进⾏⽹站性能优化 6 HTTP状态码及其含义 7 语义化的理解 8 介绍⼀下你对浏览器内核的理解 9 …...

【NumPy】关于numpy.median()函数,看这一篇文章就够了
🧑 博主简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…...

起保停电路工作原理
一、电路组成 起保停电路由电源保护设备(空气开关)、交流接触器、启动按钮、停止按钮和用电设备组成。 起保停电路的组成部分通常可分为四个部分: 保护部分:(空气开关)在电流或电压超出一定范围时自动切断…...

【Vue】Vue2使用ElementUI
目录 Element UI介绍特点Vue2使用Element安装引入ElementUI组件库 使用ElementUI用户注册列表展示其他 mint-ui介绍特点安装组件引入组件Mint-ui相关组件 Element UI 介绍 官网(基于 Vue 2.x ):https://element.eleme.cn/#/zh-CN ElementUI 是一个基于 Vue.js 的桌面端组件库…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...

恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...