C++语法系列之类型转换

article/2025/6/7 13:15:45

前言

类型转换是经常存在的情况,类型转换分为隐式类型转化 和 显式类型转化

隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败

double i = 3.3;
int b = i; //隐式类型转化 double -> int

C++搞出来了四种强制类型转换操作符,一一来介绍一下。

显式类型转化:需要用户自己处理

int *p = (int*)malloc(sizeof(int));//显示

转换当然是有问题的了

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰

所以C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符。下面来一一介绍一下。

四种指针的写法均为 xxx_cast< T >(i),必须加括号,有点像强制类型转换

一、static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换
就是说白了,你不加static_cast可以转换的或者显示类型转换的基本上加了这个也可以。类型不相关的不可以转换。
基本用法

double i = 5;
int j = static_cast<int>(i);

花里胡哨的用法:

class A {
public:explicit A(int x) {}
};
int main()
{A a(5);A a1 = static_cast<A>(5);A a2 = 5;//errorreturn 0;
}

加上explicit不允许实现隐式类型转化,但是可以玩static_cast

class Base
{};
class Derived : public Base 
{
public:int _a;
};int main()
{Base* base = new Derived();Derived* derived2 = static_cast<Derived*>(base); // 可行cout << derived2->_a << endl;return 0;
}

这样可以把父类的指针给子类,但是会有潜在的问题,子类成员无法初始化,所以这样别用,用后面的dynamic_cast

二、reinterpret_cast

有点与static_cast相反,reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型
在这里插入图片描述

int main()
{int d = 4;int* p = reinterpret_cast<int*>(d);int* pd = &d;int address = reinterpret_cast<int>(pd);return 0;
}

三、const_cast

先来看一段代码:

int main()
{const int a = 10;int* p = (int*)& a;(*p)++;cout << a << endl;cout << *p << endl;return 0;
}

在这里插入图片描述
这样是不是很奇怪啊,实际上因为a是const属性,编译器知道他是const,在输出*a的时候会直接取出来这个10,所以这里先介绍一个关键字 volatile,这个意思就告诉编译器他是不稳定的

在这里插入图片描述
加上volatile这句话:
在这里插入图片描述
但是即使加上你想直接赋值也是不可以的

volatile const int a = 10;
a = 5;//error

进而引出了const_cast的作用:
const_cast最常用的用途就是删除变量的const属性,方便赋值

int main()
{const int a = 5;int* p = const_cast<int*>(&a);*p = 4;cout << a << endl;return 0;
}

但是这样还没变。。。。所以还需要加上volatile,所以const_cast只是去掉他的属性,但是需要修改还要进一步操作(最好就别修改)
那他的作用就没有了?当然不是:
在调用一些遗留的非const接口时,若你手上只有const对象,就可以使用const_cast。示例如下:

void func(int* ptr) {// 一些非const操作*ptr += 5;
}int main() {int p = 10;const int* constPtr = &p;// func(constPtr); // errorfunc(const_cast<int*>(constPtr)); // 可行return 0;
}

实现代码的复用:
在一个类中,const和非const版本的成员函数可能有大量重复的代码。这时可以让其中一个函数调用另一个,从而减少代码冗余。
所以,const_cast主要用于在特定场景下移除对象的const或volatile属性,但在使用时必须谨慎,要确保不会对真正的常量对象进行修改,以避免引发未定义行为,

四、dynamic_cast

学过DP的应该知道dynamic是啥,dynamic意思是动态,主要用于具有继承关系的父类和子类之间的转化。
dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)(切片)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意:

  1. dynamic_cast只能用于父类含有虚函数的类(如果不含虚函数就会报错)
  2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0,与指针不同,引用不能为 nullptr,因此转换失败时会抛出异常。
class A
{
public :
virtual void f(){}
};
class B : public A
{};
void fun (A* pa)
{
B* pb1 = static_cast<B*>(pa);
B* pb2 = dynamic_cast<B*>(pa);
cout<<"pb1:" <<pb1<< endl;
cout<<"pb2:" <<pb2<< endl;
}
int main ()
{A a;B b;fun(&a);fun(&b);return 0;
}

五、RTTI(Run-Time Type Identification)

RTTI 的基本概念
运行时类型识别:允许程序在运行时查询和识别对象的实际类型,而不仅仅依赖于编译时的类型信息。
作用:主要用于解决面向对象编程中的多态性问题,特别是在需要将基类指针或引用转换为派生类类型时。
C++主要通过typeid和dynamic_cast实现。
typeid:返回一个表示对象类型的type_info对象,可以用于比较类型。
dynamic_cast:用于安全地将基类指针或引用转换为派生类类型,失败时返回nullptr(指针)或抛出异常(引用)。
decltype:用来识别类型

总结

虽然这里讲了几种方法,但是实际应用中需要小心的使用转换,建议不要使用,或者在保证安全的情况下使用


http://www.hkcw.cn/article/yyFaZTZBsa.shtml

相关文章

Python----循环神经网络(BiLSTM:双向长短时记忆网络)

一、LSTM 与 BiLSTM对比 1.1、LSTM LSTM&#xff08;长短期记忆网络&#xff09; 是一种改进的循环神经网络&#xff08;RNN&#xff09;&#xff0c;专门解决传统RNN难以学习长期依赖的问题。它通过遗忘门、输入门和输出门来控制信息的流动&#xff0c;保留重要信息并丢弃无关…

工作自动化——工作自动提炼--智能编程——仙盟创梦IDE

工作自动化中的自动提炼、自动比对代码生成日志&#xff0c;为软件开发与项目管理带来诸多好处。 自动提炼能从复杂代码中精准提取关键信息&#xff0c;节省人工梳理时间&#xff0c;开发人员可快速把握核心逻辑&#xff0c;加速项目熟悉进程。自动比对代码则及时发现版本间差异…

运行shell脚本时报错/bin/bash^M: 解释器错误: 没有那个文件或目录

Windows的换行符为\r\n&#xff0c;而linux换行符为\n。先查看一下文件是什么格式的 :set ff --查询一下格式是什么 由于使用nodepad新建的脚本&#xff0c;首选项中格式设置成了windows&#xff0c;上传到linux中报错。 解决方法 1、nodepad中【设置》首选项】修改为unix&am…

6. 基础IO

0.背景 a.访问一个文件&#xff0c;都必须先把对应的文件打开&#xff08;打开文件就是把它从磁盘加载到内存中&#xff09; b.如果一个文件&#xff0c;压根就没有被打开&#xff0c;那么它就在磁盘上 c.谁来打开&#xff1f;&#xff1f;用户通过bash&#xff0c;启动进程…

碰一碰发视频-源码系统开发技术分享

#碰一碰营销系统# #碰一碰系统# #碰一碰发视频# 架构设计哲学&#xff1a;近场通信的优雅平衡 一、核心通信技术选型 1. 双模协同传输引擎 技术协议栈延迟控制适用场景NFCISO 14443-A<100ms精准触发场景BLE 5.0GATT Profile300-500ms中距传输场景 工程决策依据&…

动态规划之网格图模型(二)

文章目录 动态规划之网格图模型&#xff08;二&#xff09;LeetCode 931. 下降路径最小和思路Golang 代码 LeetCode 2684. 矩阵中移动的最大次数思路Golang 代码 LeetCode 2304. 网格中的最小路径代价思路Golang 代码 LeetCode 1289. 下降路径最小和 II思路Golang 代码 LeetCod…

QUIC——UDP实现可靠性传输

首先我们要知道TCP存在什么样的痛点问题 TCP的升级很困难TCP建立连接的延迟网络迁移需要重新建立连接TCP存在队头阻塞问题 QUIC就是为了解决以上的问题而诞生了, 下面我会介绍QUIC的一些特性和原理 QUIC对比TCP优势: 握手建连更快 QUIC内部包含了TLS, 它在自己的帧会携带TL…

PyTorch——线性层及其他层介绍(6)

线性层 前面1,1,1是你想要的&#xff0c;后面我们不知道这个值是多少&#xff0c;取-1让Python自己计算 import torch import torchvision from torch import nn from torch.nn import Linear from torch.utils.data import DataLoader# 加载CIFAR-10测试数据集并转换为Tensor格…

bilibili批量取消关注

目录 如何使用 ​编辑 代码 如何使用 使用谷歌浏览器&#xff0c;通过F12打开调式面板&#xff0c;找到下面的位置&#xff1a; 代码 /*** 批量取消关注脚本* 自动遍历多页内容并取消所有关注*/// 配置常量 const CONFIG {CLICK_DELAY: 250, // 点击间隔时间&#…

7.RV1126-OPENCV cvtColor 和 putText

一.cvtColor 1.作用 cvtColor 是 OPENCV 里面颜色转换的转换函数。能够实现 RGB 图像转换成灰度图、灰度图转换成 RGB 图像、RGB 转换成 HSV 等等 2.API CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn 0 ); 第一个参数&#xff1a;…

研发型企业如何面对源代码保密问题

在当今数字化时代&#xff0c;研发团队面临着数据安全和工作效率的双重挑战。技术成果和源代码不仅是企业的核心资产&#xff0c;更是企业竞争力的基石。然而&#xff0c;数据泄露的风险无处不在&#xff0c;从内部员工的无意失误到外部攻击者的恶意窃取&#xff0c;都可能给企…

BeeWorks:私有化即时通讯,筑牢企业信息安全防线

在数字化时代&#xff0c;即时通讯已成为企业日常运营中不可或缺的工具。然而&#xff0c;数据安全问题一直是企业使用即时通讯服务时的重要考量因素。BeeWorks即时通讯系统以其私有化部署模式&#xff0c;为企业提供了一个安全、可靠、自主可控的沟通平台。 私有化部署&#…

akka实践之应用的扩展性问题和actor模型

如何解决应用的扩展性问题 当一个应用需要处理海量并发请求时&#xff0c;传统的开发模式往往显得力不从心&#xff0c;为什么应用需要扩展性&#xff1f; 需求增长: 用户量激增&#xff0c;数据量爆炸式增长。资源限制: 服务器、带宽、存储等资源有限。复杂性增加: 代码逻辑…

Starrocks Full GC日志分析

GC日志样例&#xff1a; [2025-06-03T07:36:06.1770800] GC(227) Pause Full (G1 Evacuation Pause) [2025-06-03T07:36:06.1960800] GC(227) Phase 1: Mark live objects [2025-06-03T07:36:06.9480800] GC(227) Cleaned string and symbol table, strings: 47009 processed,…

mapbox高阶,生成并加载等时图

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️Fill面图层样式1.4 ☘️symbol符号图层…

防火墙在OSI模型中的层级工作(2025)

1. 物理层&#xff08;L1&#xff09;& 数据链路层&#xff08;L2&#xff09; 传统防火墙&#xff1a;通常不处理L1/L2&#xff08;由交换机/网卡负责&#xff09;。 现代演进&#xff1a; MAC地址过滤&#xff1a;部分防火墙支持基于MAC地址的粗粒度策略&#xff08;如禁…

帝可得 - 运营管理APP

Android模拟器 本项目的App客户端部分已经由前端团队进行开发完成&#xff0c;并且以apk的方式提供出来&#xff0c;供我们测试使用&#xff0c;如果要运行apk&#xff0c;需要先安装安卓的模拟器。 可以选择国内的安卓模拟器产品&#xff0c;比如&#xff1a;网易mumu、雷电…

关于list集合排序的常见方法

目录 1、list.sort() 2、Collections.sort() 3、Stream.sorted() 4、进阶排序技巧 4.1 空值安全处理 4.2 多字段组合排序 4.3. 逆序 5、性能优化建议 5.1 并行流加速 5.2 原地排序 6、最佳实践 7、注意事项 前言 Java中对于集合的排序操作&#xff0c;分别为list.s…

自然语言处理(NLP)的系统学习路径规划

文章目录 一、基础准备阶段&#xff08;1-2个月&#xff09;1. 数学基础2. 编程基础3. 语言学基础 二、核心技术阶段&#xff08;3-4个月&#xff09;1. 经典NLP技术2. 深度学习模型3. 预训练模型入门 三、进阶实战阶段&#xff08;2-3个月&#xff09;1. 热门任务实战2. 大模型…

CSS3美化页面元素

1. 字体 <span>标签 字体样式⭐ 字体类型&#xff08;font-family&#xff09; 字体大小&#xff08;font-size&#xff09; 字体风格&#xff08;font-style&#xff09; 字体粗细&#xff08;font-weight&#xff09; 字体属性&#xff08;font&#xff09; 2. 文本 文…