【C++学习】C++4种类型转换详解

news2024/11/24 20:07:22

这里写目录标题

    • 🚀C语言中的类型转换
    • 🚀为什么C++需要四种类型转换
    • 🚀C++强制类型转换
      • 🚀static_cast
      • 🚀**reinterpret_cast**
      • 🚀const_cast与volatile
      • 🚀dynamic_cast


🚀C语言中的类型转换

在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型转换和显式类型转换。

  1. 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译失败
    隐式类型转换只有相近类型才可以,比如整型家族里面的。
  2. 显式类型转化:需要用户自己处理
int main()
{
	int a = 10;
	char ch = 'A';
	double d = 1.0;
	int* ptr = &a;

	//隐式类型转换
	a = ch;
	a=d;
	//强制类型转换
	a =(int)ptr;


	return 0;
}

缺陷:
转换的可视性比较差,所有的转换形式都是以一种相同形式书写,难以跟踪错误的转换。

🚀为什么C++需要四种类型转换

C风格的转换格式很简单,但是有不少缺点的:

  1. 隐式类型转化有些情况下可能会出问题:比如数据精度丢失
  2. 显式类型转换将所有情况混合在一起,代码不够清晰
    因此C++提出了自己的类型转化风格,注意因为C++要兼容C语言,所以C++中还可以使用C语言的转化风格。

🚀C++强制类型转换

标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:
static_cast、reinterpret_cast、const_cast、dynamic_cast

🚀static_cast

static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换(隐式类型转换)

举个例子:

//static_cast
int main()
{
	char ch = 'A';
	int a = static_cast<int>(ch);
	
	//类型不相近,编译报错
	//int* ptr = static_cast<int*>(ch);

	cout << a << endl;

	return 0;
}

🚀reinterpret_cast

reinterpret_cast操作符通常为操作数的位模式提供较低层次的重新解释,用于将一种类型转换为另一种不同的类型。(强制类型转换)

举个例子:

int main()
{
	char ch = 'a';
	
	//编译报错:这里是隐式类型转换,应该用static_cast
	//int a = reinterpret_cast<int>(ch);

	//不同类型且不想近
	int* ptr = reinterpret_cast<int*>(&ch);

	cout << *ptr << endl;

	return 0;
}

🚀const_cast与volatile

const_cast最常用的用途就是删除变量的const属性,方便赋值
有了强制类型转换reinterpret_cast,为什么还要增加一个呢?

我们看看下面的代码:
结合后面的调试与运行结果发现(如下图)
理论上a的值应该为3,但是运行结果为2。
原因
当编译器在知道a是一个const的变量时,会将a存放在寄存器中,需要用的时候直接去寄存器中取,我们在改变a的时候,内存中已经改变为3了,但是寄存器中还是2,监视窗口是在内存中取得。C++为了解决这个问题,所以有了const_cast与volatale。


int main()
{
	//注意:这里的a是常变量,存储在栈区的,是可以被间接修改的
	const int a = 2;
	//不能被修改
	//a++;

	//间接修改
	int* ap = (int*) & a;
	(*ap)++;

	cout << a << endl;
}

在这里插入图片描述

const_cast与volatile 的使用

void Test ()
{
  volatile const int a = 2;
  int* p = const_cast< int*>(&a );
  *p = 3;
  cout<<a <<endl;
}

运行结果:
在这里插入图片描述


🚀dynamic_cast

dynamic_cast用于将一个父类对象的指针/引用转换为子类对象的指针或引用(动态转换)
向上转型:子类对象指针/引用->父类指针/引用(不需要转换,赋值兼容规则)
向下转型:父类对象指针/引用->子类指针/引用(用dynamic_cast转型是安全的)
注意:

  1. dynamic_cast只能用于父类含有虚函数的类
  2. dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回0

代码演示:

class A
{
public:
	virtual void f() {}
};
class B : public A
{};
void fun(A* pa)
{
	// dynamic_cast会先检查是否能转换成功,能成功则转换,不能则返回
	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;
}

注意:
强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换。

注意:一个自定义类型可以类型转化为int,double等类型,前提是需要重载相关得运算符;

举个例子:

class A
{
public:
	A()
	{}

	operator int()  //不需要返回值,因为int,就是返回int
	{
		return a + B + x;
	}

private:
	char B = 'b';
	char a = 'A';
	int x = 10;
};
int main()
{
	A aa;
	int ret = (int)aa;

	cout << ret << endl;

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1607486.html

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

相关文章

buuctf——[ZJCTF 2019]NiZhuanSiWei

buuctf——[ZJCTF 2019]NiZhuanSiWei 1.绕过file_get_contents()函数 file_get_contents函数介绍 定义和用法 file_get_contents() 把整个文件读入一个字符串中。 该函数是用于把文件的内容读入到一个字符串中的首选方法。如果服务器操作系统支持&#xff0c;还会使用内存映射…

【opencv】示例-videocapture_starter.cpp 从视频文件、图像序列或连接到计算机的摄像头中捕获帧...

/** * file videocapture_starter.cpp * brief 一个使用OpenCV的VideoCapture与捕获设备&#xff0c;视频文件或图像序列的入门示例 * 就像CV_PI一样简单&#xff0c;对吧&#xff1f; * * 创建于: 2010年11月23日 * 作者: Ethan Rublee * * 修改于: 2013年4月17日 * …

【笔记】十分钟学会正确的github工作流,和开源作者们使用同一套流程

对视频十分钟学会正确的github工作流&#xff0c;和开源作者们使用同一套流程的记录&#xff0c;方便自己回顾和使用。 注1&#xff1a;一个分支 只有一个人在进行 注2&#xff1a; main和master是不同时期对主分支的命名&#xff0c;两者是同一个东西。如果项目已经有了&#…

将MySQL数据库导入到EA模型的教程

将MySQL数据库导入到EA 1.下载安装mysql-connector-odbc2.在管理工具中新增ODBC数据源3.在EA中新建项目4.链接MYSQL数据源4.1 安装64位的ODBC驱动可能出现”在连接ODBC 时发生错误&#xff0c;请相关检查设置“的提示&#xff0c;卸载后重新安装32位ODBC驱动后可以正常执行 5.导…

【1577】java网吧收费管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 网吧收费管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0…

唠一唠,氮化镓和普通快充的不同

充电器,对于手机、电脑、平板等电子产品来说,就是“生命之源”。没有它,这些设备就像鱼儿离开了水。 过去数十年,充电器市场一直在不断变革。从最早的座插式,到后来的一体式、万能充、分离式直充、快充、无线充,再到现在的氮化镓充电器,技术的更新换代快得让人眼花缭乱。 那么…

SQL Server 2022 安装及使用

SQL Server 2022 前言一、安装SQL Server 2022下载SQL Server 2022安装SQL Server 2022配置SQL Server 2022 二、安装SQL Server Management Studio下载SQL Server Management Studio安装SSMS-Setup-CHS 三、使用SQL Server 2022四、解决连接到服务器报错问题 前言 SQL Serve…

Jmeter 性能-内存溢出问题定位分析

1、堆内存溢出 ①稳定性压测一段时间后&#xff0c;Jmeter报错&#xff0c;日志报&#xff1a; java.lang.OutOfMemoryError.Java heap space ②用jmap -histo pid命令dump堆内存使用情况&#xff0c;查看堆内存排名前20个对象。 看是否有自己应用程序的方法&#xff0c;从…

C++Primer3.2 标准类型string

文章目录 初始化string对象读写string对象string的empty和size操作不同string对象的比较string的加法处理string对象的字符遍历string中的每个字符 初始化string对象 //string的初始化 void test01() { string s1; // 默认初始化&am…

YOLOv8改进 | Conv篇 | CVPR2024最新DynamicConv替换下采样(包含C2f创新改进,解决低FLOPs陷阱)

一、本文介绍 本文给大家带来的改进机制是CVPR2024的最新改进机制DynamicConv其是CVPR2024的最新改进机制,这个论文中介绍了一个名为ParameterNet的新型设计原则,它旨在在大规模视觉预训练模型中增加参数数量,同时尽量不增加浮点运算(FLOPs),所以本文的DynamicConv被提出…

AIoT人工智能物联网之deepstream

1.deepstream介绍安装 deepstream是一个很强大的工具集,能够执行数据收集、数据预处理、视频追踪、编码等功能 (1)deepstream docker 版本查询 网页查询 https://catalog.ngc.nvidia.com/containers (2)下载 deepstream docker 对应 版本 https://catalog.ngc.nvidia.c…

【微信公众平台】扫码登陆

文章目录 前置准备测试号接口配置 带参数二维码登陆获取access token获取Ticket拼装二维码Url编写接口返回二维码接收扫描带参数二维码事件编写登陆轮训接口测试页面 网页授权二维码登陆生成ticket生成授权地址获取QR码静态文件支持编写获取QR码的接口 接收重定向参数轮训登陆接…

正确解决:关于Lattic Diamond和Radiant License冲突问题(无法破解问题)

一、问题 今天工作&#xff0c;搞16nm Avant E系列FPGA&#xff0c;需要用到莱迪思的Radiant 2023.2软件&#xff08;按这个博主的安装流程Lattice Radiant 2023.1 软件安装教程&#xff09;。 安装好之后&#xff0c;设置环境变量&#xff0c;导入License.dat就是破解不了&…

从零开始学习Linux(3)----权限

1.Linux权限的概念 Linux用户&#xff1a;1.root&#xff0c;超级管理员 2.非root&#xff0c;XXX&#xff0c;普通用户 命令&#xff1a;su[用户名] 功能&#xff1a;切换用户。 su -&#xff1a;是指以root的身份重新登录一次。 普通用户切换root需要输入密码&#xff0c;…

【Java开发指南 | 第二篇】标识符、Java关键字及注释

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 标识符Java关键字Java注释 标识符 Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。 所有的标识符都应该以字母&#xff08;A-Z 或者 a-z&#xff09;,美元符&#xff08;$&#xff0…

登录解析(后端)

调试登录接口 进入实现类可以有 验证码校验 登录前置校验 用户验证 验证码校验 通过uuid获取redis 中存储的验证码信息&#xff0c;获取后对用户填写的验证码数据进行校验比对 用户验证 1.进入控制器的 /login 方法 2.进入security账号鉴权功能&#xff0c;经过jar内的流…

5.2 mybatis之autoMappingBehavior作用

文章目录 1. NONE关闭自动映射2. PARTIAL非嵌套结果映射3. FULL全自动映射 众所周知mybatis中标签< resultMap >是用来处理数据库库字段与java对象属性映射的。通常java对象属性&#xff08;驼峰格式&#xff09;与数据库表字段&#xff08;下划线形式&#xff09;是一 一…

python3.poc。sqlmapTamperPocsuite

目的&#xff0c;掌握工具的api接口&#xff0c;框架工具二次开发 ---sqlmap的api接口&#xff1a;https://www.freebuf.com/articles/web/204875.html 应用&#xff1a;配合前期信息收集的到可能存在注入点的地方&#xff0c;批量化的去扫描 #开发当前项目过程&#xff1a…

【YOLOv5】使用yolov5训练模型时报错合集

文章目录 前言问题1 -- VsCode终端无法进入Anaconda创建的虚拟环境【问题描述】【问题分析】【解决方式】方法一方法二 问题2 -- 怎么在VsCode中为项目配置Anaconda创建的虚拟环境【问题描述】【解决方式】 问题3 -- yolov5训练模型时报错RuntimeError: result type Float cant…

c语言基础总结

1. c语言概述 c语言是计算机编程语言的一种&#xff0c;编程语言用于人和机器交流。 1.1 c语言特点 简洁 ​ c语言的语法简单&#xff0c;语句清晰明了&#xff0c;使得程序易于阅读和理解 高效 ​ c语言的执行效率高&#xff0c;可以用于开发需要高性能的应用程序 可移…