C++语法系列之类型转换
前言
类型转换是经常存在的情况,类型转换分为隐式类型转化 和 显式类型转化
隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
double i = 3.3;
int b = i; //隐式类型转化 double -> int
C++搞出来了四种强制类型转换操作符,一一来介绍一下。
显式类型转化:需要用户自己处理
int *p = (int*)malloc(sizeof(int));//显示
转换当然是有问题的了
- 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
- 显式类型转换将所有情况混合在一起,代码不够清晰
所以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转型是安全的)
注意:
- dynamic_cast只能用于父类含有虚函数的类(如果不含虚函数就会报错)
- 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:用来识别类型
总结
虽然这里讲了几种方法,但是实际应用中需要小心的使用转换,建议不要使用,或者在保证安全的情况下使用
相关文章:

C++语法系列之类型转换
前言 类型转换是经常存在的情况,类型转换分为隐式类型转化 和 显式类型转化 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败 double i 3.3; int b i; //隐式类型转化 double -> intC搞出来了四种强制类…...
Qwen3 技术报告解读一
📘 Qwen3 技术报告解读:通义千问系列新成员的技术亮点与能力分析 一、论文写了什么? 本文来自阿里通义实验室发布的 《Qwen3 Technical Report》,介绍了其最新一代大语言模型 Qwen3 的技术架构、训练方法以及在多个关键任务上的…...

详解开漏输出和推挽输出
开漏输出和推挽输出 以上是 GPIO 配置为输出时的内部示意图,我们要关注的其实就是这两个 MOS 管的开关状态,可以组合出四种状态: 两个 MOS 管都关闭时,输出处于一个浮空状态,此时他对其他点的电阻是无穷大的ÿ…...

【八股消消乐】索引失效与优化方法总结
😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本专栏《八股消消乐》旨在记录个人所背的八股文,包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点ÿ…...

一步一步配置 Ubuntu Server 的 NodeJS 服务器详细实录——4. 配置服务器终端环境 zsh , oh my zsh, vim
前言 通过前面几篇文章,我们顺利的 安装了 ubuntu server 服务器,并且配置好了 ssh 免密登录服务器,也安装好了 服务器常用软件安装,接下来,我们要仔细的配置一下我们的终端环境,让服务器的终端更加好用。 一般情况下…...

数据安全合规体系构建的“三道防线“
引言 "三道防线"模型架构图 #mermaid-svg-wbeppAbwa3Vb3nL2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-wbeppAbwa3Vb3nL2 .error-icon{fill:#552222;}#mermaid-svg-wbeppAbwa3Vb3nL2 .error-text{fi…...

【Spring底层分析】Spring AOP基本使用+万字底层源码阅读分析
一、AOP基本使用 三步: 将业务逻辑组件和切面类都加入到容器中,告诉Spring哪个是切面类(Aspect)在切面类上的每一个通知方法上标注通知注解,告诉Spring何时(Before、After、Around……)何地运…...
Python数据分析及可视化中常用的6个库及函数(二)
Python数据分析及可视化中常用的6个库及函数(二) 摘要:以下是Python数据分析及可视化常用的6个库的详细介绍,包括它们的概述以及每个库中最常用的10个函数(如果某些库常用函数不足10个,则列出所有常用函数)。每个函数都附带功能描述、用法说明和使用示例。这些库…...

新德通科技:以创新驱动光通信一体化发展,赋能全球智能互联
在数字经济与AI技术高速发展的今天,光通信作为信息传输的核心基础设施,正迎来前所未有的升级浪潮。深圳新德通科技有限公司(以下简称“新德通科技”)凭借其深厚的技术积累与一体化产品布局,成为行业内的中坚力量。本文…...
Selenium的底层原理
Selenium 底层主要依赖于 WebDriver 协议(即 W3C WebDriver 规范,早期也有 JSON Wire Protocol)来实现对浏览器的远程控制,其核心架构可以分为以下几层: Selenium 客户端(Client Library) 支持多…...
PostgreSQL的扩展 auth_delay
PostgreSQL的扩展 auth_delay auth_delay 是 PostgreSQL 提供的一个安全相关扩展,主要用于防止暴力破解攻击。它通过在认证失败后引入人为延迟来增加暴力破解的难度。 一、扩展基础 功能:在认证失败后增加延迟目的:减缓暴力破解和字典攻击…...
[Java 基础]Java 是什么
Java 是一门编程语言。 查看编程语言热门排行:https://www.tiobe.com/tiobe-index/ Java 的特点: 面向对象:Java 是面向对象的语言,支持封装、继承和多态等特性。 平台无关性:Java 通过“一次编写,到处…...
Qt学习2
跟学视频 1.菜单栏和工具栏 //菜单栏最多只能有一个//菜单栏创建QMenuBar * bar menuBar();//将菜单栏放到窗口中setMenuBar(bar);//创建菜单QMenu * fileMenu bar->addMenu("开始");QMenu * editMenu bar->addMenu("编辑");//创建菜单项QAction…...

C++ 内存泄漏检测器设计
文章目录 1. C中的动态内存分配2. 什么是内存泄漏3. 内存泄漏的代码案例4. 内存泄漏检查器的设计模块1:位置信息捕获:模块2:内存分配跟踪:模块3:内存释放跟踪:模块4:泄漏记录存储:模…...
在 Linux 上安装 Nmap 工具
📦 在 Linux 上安装 Nmap 工具指南 Nmap(Network Mapper)是功能强大的网络扫描工具,以下是各种 Linux 发行版的安装方法: 🧩 通用安装方法 1. 使用包管理器安装(推荐) # Debian/…...
从零打造AI面试系统全栈开发
🤖 AI面试系统开发完整教程 📋 项目概述 本教程将带你从零开始构建一个完整的AI面试系统,包含前端、后端、AI集成和部署的全流程。 源码地址 技术栈 前端: React TypeScript Vite Vaadin Components后端: Spring Boot Spring Securi…...

破局与进阶:ueBIM 在国产 BIM 赛道的差距认知与创新实践
作为国产BIM领域的探索者,斯维尔ueBIM自诞生以来始终以追赶国际头部技术为目标,但不可否认的是,在核心功能覆盖、行业生态成熟度以及全球市场占有率等方面,我们与Autodesk Revit、Bentley Systems等国际巨头仍存在显著差距。这种差…...

分布式流处理与消息传递——向量时钟 (Vector Clocks) 算法详解
Java 实现向量时钟 (Vector Clocks) 算法详解 一、向量时钟核心原理 #mermaid-svg-JcZ1GT0r1ZNSy6W7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JcZ1GT0r1ZNSy6W7 .error-icon{fill:#552222;}#mermaid-svg-JcZ…...

20250603在荣品的PRO-RK3566开发板的Android13下的命令行查看RK3566的温度
20250603在荣品的PRO-RK3566开发板的Android13下的命令行查看RK3566的温度 2025/6/3 11:58 RK3566的cpu运行效率 top rk3566_t:/ # rk3566_t:/ # rk3566_t:/ # cd /sys/class/thermal/ rk3566_t:/sys/class/thermal # ls -l rk3566_t:/sys/class/thermal # cd thermal_zone0/ r…...

帝可得 - 设备管理
一. 需求说明 设备管理主要涉及到三个功能模块,业务流程如下: 新增设备类型: 允许管理员定义新的售货机型号,包括其规格和容量。 新增设备: 在新的设备类型定义后,系统应允许添加新的售货机实例,并将它们分配到特定的…...
FTXUI配置
对于 FTXUI 的安装与配置, 官方已经给出了三种方案. 第一种: 使用 FetchContent 远程拉取第二种: 在你本地安装 FTXUI 库, 然后通过 find_package 使用第三种: 使用 Git 子模块 FetchContent 无需手动下载安装 FTXUI, 通过 CMake 自动从 GitHub 拉取并编译依赖 include(Fet…...
Caliper压力测试
目前FISCO BCOS适配的Caliper版本为0.2.0,请在部署Caliper运行环境时确保Caliper的版本为0.2.0,如在部署或使用过程中遇到任何问题,请优先参考 https://github.com/FISCO-BCOS/FISCO-BCOS/issues/1248 中的解决方案进行排查。 1. 环境要求 …...

【iOS安全】使用LLDB调试iOS App | LLDB基本架构 | LLDB安装和配置
LLDB基本架构 参考: https://crifan.github.io/ios_re_dynamic_debug/website/debug_code/lldb_debugserver.html https://book.crifan.org/books/ios_re_debug_debugserver_lldb/website/ LLDB安装和配置 1. 让iPhone中出现/Developer/usr/bin/debugserver 最初…...
一、核心概念深入解析
一、核心概念深入解析 1. shared_ptr 的线程安全性澄清 引用计数是原子操作:shared_ptr 的引用计数(use_count)在多线程中递增 / 递减是安全的(原子操作),但对象本身的读写需额外同步(如 std:…...
python直方图
在Python中,绘制直方图(Histogram)是一项非常常见的任务,通常用于数据可视化,以展示数据的分布情况。Python中有多种库可以绘制直方图,其中最常用的两个库是Matplotlib和Seaborn。此外,Pandas库…...
[特殊字符] Unity 性能优化终极指南 — Text / TextMeshPro 组件篇
UGUI Text组件的不当使用及其性能瓶颈与优化 在Unity UGUI系统中,Text 组件(或其升级版 TextMeshPro)是显示文本信息的核心元素。然而,如果不当使用,它极易成为UI性能瓶颈的罪魁祸首,尤其是在预制体、属性…...

Idea 配置 Maven 环境
下载 Maven 官网:https://maven.apache.org/index.html 点击左侧 Downloads,然后选择 Files 中的 zip 包下载(下载慢可以使用迅雷) 配置 Maven 将压缩包解压,比如我解压后放到了 D:\developer\environment\apache-…...
git clone报错:SSL certificate problem: unable to get local issuer certificate
上述报错的完整信息是: Cloning into test... fatal: unable to access https://github.com/xxxx/xxxx.git/: SSL certificate problem: unable to get local issuer certificate 该报错表示 Git 在使用 HTTPS 协议克隆仓库时,无法验证 GitHub 的 SSL …...

Kafka 如何保证不重复消费
在消息队列的使用场景中,避免消息重复消费是保障数据准确性和业务逻辑正确性的关键。对于 Kafka 而言,保证不重复消费并非单一机制就能实现,而是需要从生产者、消费者以及业务层等多个维度协同配合。接下来,我们将结合图文详细解析…...
SpringBoot整合MyBatis完整实践指南
在Java企业级应用开发中,SpringBoot和MyBatis的组合已经成为主流的技术选型方案之一。本文将详细介绍如何从零开始搭建一个基于SpringBoot和MyBatis的项目,包括环境配置、数据库设计、实体类创建、Mapper接口编写以及实际应用等完整流程。 一、环境准备…...