【C++】告别“类型转换”踩坑,从基础到四种核心强制转换方式

【C++】告别“类型转换”踩坑,从基础到四种核心强制转换方式

各位大佬好,我是落羽!一个坚持不断学习进步的学生。
如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步!
也欢迎关注我的blog主页:
落羽的落羽

文章目录

一、回顾C语言的类型转换

C语言的类型转换主要是隐式类型转换和强制类型转换:

  • 隐式类型转换,是编译器在特定情况下自动进行的类型转换,通常发生在不同类型的表达式运算中。主要是整型之间、整型与浮点型之间、浮点型之间的转换。
int a =1;double b =2.234; a = b;
  • 强制类型转换:是我们通过显式语法手动指定的类型转换,主要是整型和指针、指针和指针之间的转换。
int a =1;char* p =(char*)a;int* p1 =(int*)malloc(sizeof(int));

但是,并非所有类型直接都能转换。例如double就无法转为指针类型。

在这里插入图片描述

二、C++中的类型转换

1. 内置类型转为自定义类型

随着自定义类型的广泛使用,C++也支持了内置类型和自定义类型之间的相互转换:

  • 内置类型转换为自定义类型,需要自定义类型的相关构造函数支持。非常好理解,用内置类型转换为自定义对象,就相当于构造一个自定义对象。
classA{public:A(int a):a1(a),a2(a){}private:int a1;int a2;};
在这里插入图片描述

而当构造函数前加上关键字explicit,可以使这个构造函数不支持隐式类型转换。这就是之前我们学习智能指针时构造函数加了它的原因,我们不希望一个普通指针悄悄转换为智能指针。不过,还是支持强制类型转换的

在这里插入图片描述

2. 自定义类型转为内置类型

一个自定义类型对象想要转换为内置类型,需要内部重载operator()。这里不是常规的运算符重载,和仿函数中重载operator()的写法也不一样。它的用法是operator 类型(){...}(也可以加explicit修饰),转换的方式是函数体内自定义的,举个例子:

classA{public:A(int a):a1(a),a2(a){}operatorint(){return a1 + a2;}private:int a1;int a2;};
在这里插入图片描述

智能指针中,关于向bool类型的转换,就是这样写的:

在这里插入图片描述

3. 自定义类型之间的转换

自定义类型之间的转换,也是需要有相关的构造函数,很好理解,不再赘述。

4. 类型安全与C++的四种强制类型转换方式

4.1 什么是类型安全?

类型安全是指,编程语言在编译和运行时提供保护机制,避免非法的类型转换和操作,导致出现内存访问错误等,从而减少程序运行时的错误。

C语言不是类型安全的语言, 因为C语言允许隐式类型转换,一些特殊情况下就会导致越界访问的内存错误。不合理的使用强制类型转换也会导致问题,比如一个int*的指针强转成 double*的话,访问就会出现越界。
C++兼容C语言,也支持隐式类型转换和强制类型转换,它也不是类型安全的语言。因此,C++提出了四个显示强制类型转换 操作符static_cast / reinterpret_cast / const_cast / dynamic_cast,就是为了让类型转换相对而言更安全。

4.2 static_cast

static_cast用于两个意义相近的类型之间的转换,比如整型之间、整型和浮点型之间、普通类型和其引用类型之间等。

double a =1.234;int b =static_cast<int>(a);float c =static_cast<float>(b);int&& d =static_cast<int&&>(b);

4.3 reinterpret_cast

reinterpret_cast用于底层的类型转换,比如将一种类型的指针/引用直接转换为另一种类型。这种类型的转换后,对于内存的访问方式就会改变了,因此使用时需要很谨慎,自己要清楚明白使用后是否会出现问题。

int a =1;int* p1 =&a;char* p2 =reinterpret_cast<char*>(p1);

4.4 const_cast

const_cast用于const对象向非const对象的转换,会去掉const属性,使用时同样需要谨慎。

在这里插入图片描述

4.5 dynamic_cast

dynamic_cast主要用于多态类型之间的转换,尤其是用于基类指针/引用向派生类指针/引用的转换,因为派生类的指针/引用向基类指针/引用的转换是天然支持的(也就是切片)。
但是,它不是简单基类转换为派生类。一个基类的指针/引用,它可能指向的是一个基类的对象,也可能指向的是一个派生类对象的切片。dynamic_cast只能作用在后者,只有这个基类指针/引用指向的是派生类对象的切片,才能完成转换。对于前者情况,就不能转换,如果是基类指针指向基类,转换失败返回nullptr,如果是基类引用指向基类,转换失败抛出bad_cast异常

dynamic_cast还要求基类必须是多态类型,也就是必须有虚函数,因为它的运行时通过虚表中存储的type_info来判断一个基类指针/引用指向的是基类对象还是派生类对象。

classA{public:virtualvoidfunc(){}};classB:publicA{};
在这里插入图片描述

本篇完,感谢阅读

Read more

ClawPanel — 开源 OpenClaw 智能管理面板,20+ 通道接入 / 多模型配置 / Docker 一键部署

ClawPanel — 开源 OpenClaw 智能管理面板,20+ 通道接入 / 多模型配置 / Docker 一键部署

🐾 一个比官方控制台更强大的 OpenClaw 可视化管理工具,支持 QQ、微信、Telegram、Discord 等 20+ 通道统一管理,多 AI 模型提供商配置,技能中心,版本管理,环境检测,Docker 一键部署。 📌 项目简介 ClawPanel 是一个基于 React + TypeScript + Express 的 OpenClaw 智能管理面板,旨在为 OpenClaw 用户提供一个比官方控制台更强大、更直观的可视化管理工具。 项目前身是 openclaw-im-manager(一个简单的 QQ 机器人管理后台),经过 4 个大版本迭代,现已进化为功能完整的 OpenClaw 全能管理面板。 GitHub 地址:https://github.com/zhaoxinyi02/ClawPanel

By Ne0inhk
Ubuntu 25.10桌面版安装

Ubuntu 25.10桌面版安装

ubuntu-25.10-desktop-amd64安装教程,本次是在Vmware workstation虚拟机中进行安装 省略Vmware workstation安装及虚拟机环境设置只介绍Ubuntu 25.10桌面版安装过程和简单的配置 1、Vmware workstation安装包及鸡火马可在网上找 2、ubuntu-25.10安装镜像可在如清华、阿里、腾讯等镜像源进行下载 1、挂载镜像后开机 选择 尝试或安装,按回车键确认,方向键选择 然后会卡一会界面,等待一会 2、选择开机语言 选择系统的语言,有中文简体可以选 选好后点下一步 3、选择一些功能 然后是一下功能选择,没特殊需求可以直接下一步 4、键盘设置 按常规习惯选美式英语键盘,也可以选默认的汉语键盘 5、网络设置 然后就是安装前的软件选择,没网就选现在不连接到互联网,但是没网会影响到后面系统安装过程中的软件预装 6、安装还是试用 这里选择你是要安装还是试用,如果选试用等于是没有把系统安装到硬盘但是可以测试一些兼容性 7、手动安装还是自动安装 这里如果选下面自动化需

By Ne0inhk
YOLOv12环境配置,手把手教你使用YOLOv12训练自己的数据集和推理(附YOLOv12网络结构图),全文最详细教程

YOLOv12环境配置,手把手教你使用YOLOv12训练自己的数据集和推理(附YOLOv12网络结构图),全文最详细教程

文章目录 * 前言 * 一、YOLOv12代码下载地址 * 1.YOLOv12模型结构图 * 二、YOLO环境配置教程 * 1.创建虚拟环境 * 2.激活虚拟环境 * 3.查询自己电脑可支持最高cuda版本是多少(无显卡的同学可以跳过这个步骤) * 4.pytorch安装 * 5.验证 PyTorch GPU 是否可用(没有显卡的同学不用看这个步骤) * 6.安装其他依赖 * 7.补充(flash_attn环境) * 三、数据集准备 * LabelImg & Labelme * LabelImg(仅限矩形检测框) * Labelme * X-AnyLabeling * 旋转框 (OBB) 标注工具:roLabelImg * 1.目标检测数据集标注软件 * 2.voc数据集格式转换 * 3.数据集划分 * 4.修改yolo的训练配置文件

By Ne0inhk
【Linux】UDP 网络编程

【Linux】UDP 网络编程

目录 一. 认识相关网络接口 1. socket 套接字 2. sockaddr_in 网络地址结构体 3. bind绑定 4. recvfrom 接收网络数据 5. sendto 发送网络数据 6. ntohs / ntohl 网络字节序转换 7. htons / htonl 主机字节序端口号转换 8. inet_ntoa / inet_ntop 网络字节序IP地址转换 二. Echo Server 实现 1. 前备日志和封装锁 (1)Mutex.hpp (2)Log.hpp 2. 服务端封装 3. 客户端/服务端运行 (1)

By Ne0inhk