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

news2025/6/5 8:02:08

前言

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

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

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;//error
	return 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); // error
    func(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.coloradmin.cn/o/2397973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

详解开漏输出和推挽输出

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

【八股消消乐】索引失效与优化方法总结

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本专栏《八股消消乐》旨在记录个人所背的八股文&#xff0c;包括Java/Go开发、Vue开发、系统架构、大模型开发、具身智能、机器学习、深度学习、力扣算法等相关知识点&#xff…

一步一步配置 Ubuntu Server 的 NodeJS 服务器详细实录——4. 配置服务器终端环境 zsh , oh my zsh, vim

前言 通过前面几篇文章&#xff0c;我们顺利的 安装了 ubuntu server 服务器&#xff0c;并且配置好了 ssh 免密登录服务器&#xff0c;也安装好了 服务器常用软件安装,接下来&#xff0c;我们要仔细的配置一下我们的终端环境&#xff0c;让服务器的终端更加好用。 一般情况下…

数据安全合规体系构建的“三道防线“

引言 "三道防线"模型架构图 #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基本使用 三步&#xff1a; 将业务逻辑组件和切面类都加入到容器中&#xff0c;告诉Spring哪个是切面类&#xff08;Aspect&#xff09;在切面类上的每一个通知方法上标注通知注解&#xff0c;告诉Spring何时&#xff08;Before、After、Around……&#xff09;何地运…

新德通科技:以创新驱动光通信一体化发展,赋能全球智能互联

在数字经济与AI技术高速发展的今天&#xff0c;光通信作为信息传输的核心基础设施&#xff0c;正迎来前所未有的升级浪潮。深圳新德通科技有限公司&#xff08;以下简称“新德通科技”&#xff09;凭借其深厚的技术积累与一体化产品布局&#xff0c;成为行业内的中坚力量。本文…

C++ 内存泄漏检测器设计

文章目录 1. C中的动态内存分配2. 什么是内存泄漏3. 内存泄漏的代码案例4. 内存泄漏检查器的设计模块1&#xff1a;位置信息捕获&#xff1a;模块2&#xff1a;内存分配跟踪&#xff1a;模块3&#xff1a;内存释放跟踪&#xff1a;模块4&#xff1a;泄漏记录存储&#xff1a;模…

破局与进阶:ueBIM 在国产 BIM 赛道的差距认知与创新实践

作为国产BIM领域的探索者&#xff0c;斯维尔ueBIM自诞生以来始终以追赶国际头部技术为目标&#xff0c;但不可否认的是&#xff0c;在核心功能覆盖、行业生态成熟度以及全球市场占有率等方面&#xff0c;我们与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…

帝可得 - 设备管理

一. 需求说明 设备管理主要涉及到三个功能模块&#xff0c;业务流程如下&#xff1a; 新增设备类型: 允许管理员定义新的售货机型号&#xff0c;包括其规格和容量。 新增设备: 在新的设备类型定义后&#xff0c;系统应允许添加新的售货机实例&#xff0c;并将它们分配到特定的…

【iOS安全】使用LLDB调试iOS App | LLDB基本架构 | LLDB安装和配置

LLDB基本架构 参考&#xff1a; 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 最初…

Idea 配置 Maven 环境

下载 Maven 官网&#xff1a;https://maven.apache.org/index.html 点击左侧 Downloads&#xff0c;然后选择 Files 中的 zip 包下载&#xff08;下载慢可以使用迅雷&#xff09; 配置 Maven 将压缩包解压&#xff0c;比如我解压后放到了 D:\developer\environment\apache-…

Kafka 如何保证不重复消费

在消息队列的使用场景中&#xff0c;避免消息重复消费是保障数据准确性和业务逻辑正确性的关键。对于 Kafka 而言&#xff0c;保证不重复消费并非单一机制就能实现&#xff0c;而是需要从生产者、消费者以及业务层等多个维度协同配合。接下来&#xff0c;我们将结合图文详细解析…

RNN结构扩展与改进:从简单循环网络到时间间隔网络的技术演进

本文系统介绍 RNN 结构的常见扩展与改进方案。涵盖 简单循环神经网络&#xff08;SRN&#xff09;、双向循环神经网络&#xff08;BRNN&#xff09;、深度循环神经网络&#xff08;Deep RNN&#xff09; 等多种变体&#xff0c;解析其核心架构、技术特点及应用场景&#xff0c;…

类 Excel 数据填报

类 Excel 填报模式&#xff0c;满足用户 Excel 使用习惯 数据填报&#xff0c;可作为独立的功能模块&#xff0c;用于管理业务流程、汇总采集数据&#xff0c;以及开发各类数据报送系统&#xff0c;因此&#xff0c;对于报表工具而言&#xff0c;其典型场景之一就是利用报表模…

Office文档图片批量导出工具

软件介绍 本文介绍一款专业的Office文档图片批量导出工具。 软件特点 这款软件能够批量导出Word、Excel和PPT中的图片&#xff0c;采用绿色单文件设计&#xff0c;体积小巧仅344KB。 基本操作流程 使用方法十分简单&#xff1a;直接将Word、Excel或PPT文件拖入软件&#xf…

【iOS】ARC 与 Autorelease

ARC 与 Autorelease 文章目录 ARC 与 Autorelease前言何为ARC内存管理考虑方式自己生成的对象,自己持有非自己生成的对象,自己也可以持有不再需要自己持有的对象时释放非自己持有的对象无法释放 ARC的具体实现编译期和运行期ARC做的事情ARC实现: __autoreleasing 与 Autoreleas…

铁电液晶破局 VR/AR:10000PPI 重构元宇宙显示体验

一、VR/AR 沉浸感困境&#xff1a;传统显示技术的天花板在哪&#xff1f; &#xff08;一&#xff09;纱窗效应与眩晕感&#xff1a;近眼显示的双重枷锁 当用户戴上 VR 头显&#xff0c;眼前像素网格形成的 “纱窗效应” 瞬间打破沉浸感。传统液晶 500-600PPI 的像素密度&…

竞争加剧,美团的战略升维:反内卷、科技与全球化

5月26日&#xff0c;美团发布2025年第一季度业绩报告&#xff0c;交出了一份兼具韧性与创新性的成绩单。 报告显示&#xff0c;公司一季度总营收866亿元&#xff0c;同比增长18%&#xff1b;核心本地商业收入643亿元&#xff0c;同比增长18%&#xff1b;季度研发投入58亿元&a…