当前位置: 首页 > news >正文

C++的类型转换

前言

        我们都知道C++是兼容C语言的在C语言中存在两种方式的类型转换,分别是隐式类型转换和显示类型转换(强制类型转换),但是C++觉得C语言的这套东西是够好,所以在兼容C语言的基础上又搞了一套自己的关于类型转换的东西。

目录

1.C语言中的类型转换

2.C++中的类型转换

        3.1static_cast

        3.2reintrepret_cast

        3.3const_cast

        3.4dynamic_cast 

3.RTTI


1.C语言中的类型转换

        在C语言中如果赋值运算符的左右两侧值的类型不同,或者形参与实参的类型不匹配,或者返回值类型与接受返回值类型不匹配,就会发生类型转换, C语言中存在两种方式的类型转换,分别是隐式类型转换和显示类型转换(强制类型转换)。

        1.隐式类型转换:编译器在编译的阶段自己进行,能转就转,不能转就会报错,编译失败。一般用于相近的类型

        2.显示类型转换:需要用户自己处理。

         

void Test1()
{int a = 10;double b = 2.2;//隐式类型转换a = b;cout << a;//显示类型转换--强制类型转换int* p = (int*)a;cout << p << endl;
}

        缺点:比较暴力,可视性不够好,所有的转换都是以一种形式书写的,难以跟踪错误的转换。 

2.C++中的类型转换

         所以C++在兼容C语言的基础之上搞出来了自己的一套东西,来对C语言做的不好的地方进行优化,但是这里只是建议使用C++自己的类型转换方式,还是兼容C语言的方式的。

        标准的C++引入了四种命名的强制类型转换符:

        static_cast,reinterpret_cast,const_cast,dynamic_cast.

        3.1static_cast

        statci_cast用于非多态的类型转换,和C语言中的隐式类型转换一样。不能用于两个不相关的类型之间的转换。

void Test2()
{int a = 10;double b = 2.3;a = static_cast<int>(b);//和C语言中的隐式类型转换一致cout << a;
}

 

        3.2reintrepret_cast

        reinterpret_cast用于两个不想关的类型之间的强制类型转换,与C语言中的强制类型转换大部分是一致的。(除了const类型等的转换)

void Test3()
{int a = 9;double* p = nullptr;p = reinterpret_cast<double*>(a);cout << p << endl;
}

 

        3.3const_cast

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

void Test4()
{const int c = 90;int* p = const_cast<int*>(&c);cout << *p << endl;
}

         这里有一个有意思的问题,我们可以一起来看看。

        如果将*p的值改了,c的值会变吗?

void Test4()
{const int c = 90;int* p = const_cast<int*>(&c);cout << *p << endl;//如果将*p改为10,c的值会变吗?(*p) = 20;cout <<"*p = " << *p << endl;cout<<"c = " << c << endl;
}

        结果是不会改变的,为什么呢?

 

        因为在变量c是const修饰的,所以理论上是不会改变的,所以编译器会对变量c进行处理,将变量c的值存储在寄存器中,虽然*p = 20,确实改变了 变量c的值,但是程序在执行的时候并没有去内存中拿C的值,而是去寄存器中拿c的值所以就会看到这样的结果,实际上是编译器的优化导致的。

        怎么解决这个问题呢?需要对变量加关键字volatile。

void Test4()
{// const int c = 90;volatile const int c = 90;int* p = const_cast<int*>(&c);cout << "c = " << c << endl;//如果将*p改为10,c的值会变吗?(*p) = 20;cout <<"*p = " << *p << endl;cout<<"c = " << c << endl;
}

        加上volatile后,程序会去内存中取这个变量的值。 

        3.4dynamic_cast 

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

        向上转型:子类对象的指针/引用给父类对象的指针/引用的过程(不需要转换,赋值兼容规则),也就是我们常说的切片

        向下转型:父类对象的指针/引用给子类对象的指针/引用的过程(用dynamic_cast进行类型转换是安全的) 。

        注意:

        1.dynamic_cast只能用于父类是多态类的情况,也就是父类必须有虚函数。

        2.dynamic_cast会先检查转换是否成功如果成功则转换,失败则返回0

        

class A
{
public:virtual void func(){}int _a = 10;
};
class B :public A
{
public:int _b = 20;
};
void Fun(A& a)
{B *b = (B*)&a;cout << b->_a << endl << b->_b << endl;
}
int main()
{A a1;B b1;Fun(a1);//如果没有采用dynamic_cast进行动态类型转化这里就会报错,cout打印的是随机值,因为这块空间是不允许被访问的//Fun(b1);return 0;
}

         如果没有采用dynamic_cast进行动态类型转化这里就会报错,cout打印的是随机值,因为这块空间是不允许被访问的。

class A
{
public:virtual void func(){}int _a = 10;
};
class B :public A
{
public:int _b = 20;
};
void FunDynamic(A& a)
{B* pb = dynamic_cast<B*>(&a);if (pb)//通过返回值进行判断{cout << pb->_a << endl << pb->_b << endl;}else{cout << "类型转换失败!" << endl;}
}
int main()
{A a1;B b1;FunDynamic(a1);FunDynamic(b1);return 0;
}

        dynamic_cast的原理:

        为什么dynamic只能用于父类是多态类的情况呢?这就和dynamic的实现原理有关系了,在虚表上方中有一个位置是专门表示类的类别的,dynamic_cast就是专门去这块空间中取数据判断类的类别,从而区分到底是父类对象还是子类对象,如果是父类对象就会返回0。 这就是为什么要是父类是多态类的原因。

         

3.RTTI

        RTTI:Run-time Type identification的简称 ,即运行时类型识别。

        C++通过一下方式来支持RTTI:

        1.typeid运算符

        2.dynamic_cast

        3.decltype

相关文章:

C++的类型转换

前言 我们都知道C是兼容C语言的在C语言中存在两种方式的类型转换&#xff0c;分别是隐式类型转换和显示类型转换&#xff08;强制类型转换&#xff09;&#xff0c;但是C觉得C语言的这套东西是够好&#xff0c;所以在兼容C语言的基础上又搞了一套自己的关于类型转换的东西。 目…...

【Selenium2+python】自动化unittest生成测试报告

前言 批量执行完用例后&#xff0c;生成的测试报告是文本形式的&#xff0c;不够直观&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成HTML格式的。 unittest里面是不能生成html格式报告的&#xff0c;需要导入一个第三方的模块&#xff1a;HTMLTestRunner 一、导…...

【APISIX】W10安装APISIX

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关&#xff0c;提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。以下简单介绍Windows下借助Docker Desktop来安装APISIX。 具体应用场景可参考官网&#xff08;https://apisix.…...

[Linux]动静态库

[Linux]动静态库 文章目录 [Linux]动静态库见一见库存在库的原因编写库模拟编写静态库模拟使用静态库模拟编写动态库模拟使用静态库 库的加载原理静态库的加载原理动态库的加载原理 库在可执行程序中的编址策略静态库在可执行程序中的编址策略动态库在可执行程序中的编址策略 见…...

2023高教社杯数学建模国赛C题思路解析+代码+论文

如下为C君的2023高教社杯全国大学生数学建模竞赛C题思路分析代码论文 C题蔬菜类商品的自动定价与补货决策 在生鲜商超中&#xff0c;一般蔬菜类商品的保鲜期都比较短&#xff0c;且品相随销售时间的增加而变差, 大部分品种如当日未售出&#xff0c;隔日就无法再售。因此&…...

macos13 arm芯片(m2) 搭建hbase docker容器 并用flink通过自定义richSinkFunction写入数据到hbase

搭建hbase docker容器 下载镜像 https://hub.docker.com/r/satoshiyamamoto/hbase/tags 点击run 使用镜像新建容器 填写容器名和 容器与宿主机的端口映射 测试 通过宿主机访问容器内的hbase webUI http://localhost:60010/master-status...

FLV封装格式

摘要&#xff1a;本文描述了FLV的文件格式。   关键字&#xff1a;FLV 1 简介 FLV流媒体格式是sorenson公司开发的一种视频格式&#xff0c;全称为Flash Video。 它的出现有效地解决了视频文件导入Flash后&#xff0c;使导出的SWF文件体积庞大&#xff0c;不能在网络上很好的…...

[NLP]LLM---FineTune自己的Llama2模型

一 数据集准备 Let’s talk a bit about the parameters we can tune here. First, we want to load a llama-2-7b-hf model and train it on the mlabonne/guanaco-llama2-1k (1,000 samples), which will produce our fine-tuned model llama-2-7b-miniguanaco. If you’re …...

git在linux情况下设置git 命令高亮

只需要执行下面这个命令&#xff0c;这样就可以在查看git status明亮的时候高亮显示。 git config --global color.status auto未设置前 谁知之后...

C++ 表驱动方法代替if-else

连着用几十个if-else代码&#xff0c;运行效率不高&#xff0c;关键还手累,记得改成表驱动方法 #include <iostream> #include <unordered_map> #include <functional>using namespace std;void handleCondition1() {// 处理条件 1 的代码std::cout <<…...

2023国赛数学建模E题思路分析 - 黄河水沙监测数据分析

# 1 赛题 E 题 黄河水沙监测数据分析 黄河是中华民族的母亲河。研究黄河水沙通量的变化规律对沿黄流域的环境治理、气候变 化和人民生活的影响&#xff0c; 以及对优化黄河流域水资源分配、协调人地关系、调水调沙、防洪减灾 等方面都具有重要的理论指导意义。 附件 1 给出了位…...

cadence后仿真/寄生参数提取/解决pin口提取不全的问题

post-simulation设置顺序与规则 1.Rules 设置 2.inputs设置 3.outputs设置 4.PEX 设置 会出现错误1&#xff0c;后有解决方案 第一步 :Netlist 第二步&#xff1a;LVS 5.RUN PEX 先RUN&#xff0c;后按照图中1 2 3步骤操作 点击OK之后&#xff0c;显示Calibre信息&#xff…...

Vue中实现3D得球自动旋转

具体实现 安装echarts 在终端下安装echarts npm install -D echarts 安装echarts-gl 在终端下安装echarts-gl npm install -D echarts-gl earth3D组件 earth3D.vue <template><div class"globe3d-earth-container" ><div class"globe3d-earth&qu…...

使用wkhtmltoimage实现生成长图分享

需求 用户可以选择以长图的形式分享本网页 方法 wkhtmltopdf wkhtmltopdf url filewkhtmltoimage url file java Runtime.getRuntime().exec() 下载 直接去官网下载对应的版本&#xff1a;官网 命令行使用WK > wkhtmltopdf https://www.nowcoder.com /opt/project/…...

新风机未来什么样?

新风机在未来将会有许多令人期待的发展和改进&#xff0c;让我们一起来看一看吧&#xff01;以下是新风机未来的一些可能性&#xff1a; 智能化和智能家居&#xff1a;新风机将更多地与智能家居系统整合&#xff0c;通过物联网和人工智能技术&#xff0c;实现智能控制和智能调节…...

python的几种数据类型的花样玩法(一)

Python是一种动态类型语言&#xff0c;这意味着在Python中&#xff0c;你可以操作多种不同的数据类型&#xff0c;而且这些数据类型可以自动转换。以下是一些Python数据类型的花样玩法&#xff1a; 数字&#xff1a; 整数 (1, 100, -786 等) 浮点数 (1.1, -78.4, 3.14159 等)…...

python回调函数之获取jenkins构建结果

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 需求背景&#xff1a; 现在用jenkins构建自动化测试&#xff08;2个job&#xff09;&#xff0c;公司现将自动化纳入到发布系统 要求每次构建成功之后&am…...

Docker底层实现

Docker采用c/s架构&#xff0c;Docker守护进程&#xff08; Daemon &#xff09;作为服务端&#xff0c;接受来自客户端&#xff08;命令行&#xff09;的请求&#xff0c;并处理这些请求&#xff08;创建、运行、分发容器&#xff09; 。客户端和服务端既可以运行在一个机器上…...

PY32F003F18之RS485通讯

PY32F003F18将USART2连接到RS485芯片&#xff0c;和其它RS485设备实现串口接收后再转发的功能。 一、测试电路 二、测试程序 #include "USART2.h" #include "stdio.h" //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf() #include "…...

概率论与数理统计学习笔记(7)——全概率公式与贝叶斯公式

目录 1. 背景2. 全概率公式3. 贝叶斯公式 1. 背景 下图是本文的背景内容&#xff0c;小B休闲时间有80%的概率玩手机游戏&#xff0c;有20%的概率玩电脑游戏。这两个游戏都有抽卡环节&#xff0c;其中手游抽到金卡的概率为5%&#xff0c;端游抽到金卡的概率为15%。已知小B这天抽…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...