【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 的桌面端组件库…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...
6.9本日总结
一、英语 复习默写list11list18,订正07年第3篇阅读 二、数学 学习线代第一讲,写15讲课后题 三、408 学习计组第二章,写计组习题 四、总结 明天结束线代第一章和计组第二章 五、明日计划 英语:复习l默写sit12list17&#…...
