C++:类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)、RTTI

news2024/11/15 13:23:45

C++:类型转换(static_cast、reinterpret_cast、const_cast、dynamic_cast)、RTTI

  • 一、C语言类型转换
  • 二、C++新增强制类型转换
    • 2.1 新增类型转换:static_cast
    • 2.2 新增类型转换: reinterpret_cast
    • 2.3 新增类型转换:const_cast
  • 2.4 新增类型转换:dynamic_cast
  • 三、 什么是RTTI ?

一、C语言类型转换

 在C中支持类型转换, 分为隐式类型转换和显示类型转换。但C中类型转换不是非常规范不规范,存在以下问题:

  1. 隐式类型转换:编译器在编译阶段自动转换。如果不能转换,编译失败。
  2. 显示类型转换:用户自己处理。

二、C++新增强制类型转换

 由于C语言两种类型转换方式都存在缺陷:隐式类型转换会导致诸如数据精度丢失等问题;而显示类型转化代码不清晰。所以C++在兼容C的基础之上,增加了4中强制类型转换:static_cast、reinterpret_cast、const_cast、dynamic_cast。

2.1 新增类型转换:static_cast

static_cast用于非多态的类型的转化,即静态转化。static_cast和C中的隐式类型转换类似,编译器会自动进行类型转换。如果不能转换,则编译失败!

int main()
{
	double d = 123.12l;
	int i = static_cast<int>(d);
	return 0;
}

2.2 新增类型转换: reinterpret_cast

reinterpret_cast对标的是C中的显示类型转换。需要注意的是显示类型转换通常会伴随风险,使用reinterpret_cast不会进行类型安全检查。

int main()
{
	int i = 3;
	//int* p = static_cast<int*>(i); //error
	int* p = reinterpret_cast<int*>(i);
	return 0;

2.3 新增类型转换:const_cast

const_cast用于去除变量的const属性,使变量能够进行赋值操作。
【实例】:

int main()
{
	const int i = 2;
	int* p = const_cast<int*>(&i);//删除常变量i的const属性
	(*p)++;


	//cout << i << ":" << *p << endl;
	printf("i=%d, *p=%d\n", i, *p);
	return 0;
}

在这里插入图片描述

  • 既然我们已经使用const_cast删除了变量iconst属性,为什么这里i的结果认为2?
  • 原因在于编译器的优化。当一个变量为const属性时,编译器认为该变量不在被修改,所以会用一个寄存器直接保存该变量的结果;或者在编译阶段直接类似宏替换,将i替换为2。

所以我们可以通过关键字volatile禁止编译器对常变量的优化!!

int main()
{
	volatile const int i = 2;
	int* p = const_cast<int*>(&i);//删除常变量i的const属性
	(*p)++;


	//cout << i << ":" << *p << endl;
	printf("i=%d, *p=%d\n", i, *p);
	return 0;
}

在这里插入图片描述

  1. 这里输出时不要用cout。原因在于这里使用volatile后,由于C++标准输出库存在缺陷,没有匹配到正确的重载函数。

2.4 新增类型转换:dynamic_cast

dynamic_cast用于动态转换,将一个父类对象的指针或引用转换为一个子类对象的指针或引用。

  1. 向上转换:子类对象指针/引用->父类指针/引用(我们认为该过程是天然的,不产生临时变量。通过赋值兼容规则(切片)直接将子类对象指针/引用给父类指针/引用)
  2. 向下转换:父类指针/引用->子类对象指针/引用。这种情况下,如果直接强转类型,可能回到住越界访问的风险。而dynamic_cast则可以避免该问题。(具体看实例)

tips:

  • dynamic_cast只能用于父类含有虚函数的类!!
  • dynamic_cast会先检查能否转换成功。如果能成功,则进行转换。否则返回一个空指针!!
void func(A* pa)
{
	//不安全, 原因在于如果是一个A类型的指针转递给pa,此时后续访问_b是发生越界访问
	//B* ptr = (B*)pa;

	//使用dynamic_cast,如果将A类型的指针转递给pa会转换失败,返回空指针
	//而将B类型的指针转递给pa, 转换成功,恢复到原始状态
	B* ptr = dynamic_cast<B*>(pa);
	if (ptr)
	{
		ptr->_a++;
		ptr->_b++;
		cout << ptr->_a << ":" << ptr->_b << endl;
	}
	else
	{
		cout << "转换失败" << endl;
	}
}

int main()
{
	A a;
	B b;
	cout << "B b -> func(&a):" << endl;
	func(&a);//转换失败
	cout << endl;

	cout << "A a -> func(&b):" << endl;
	func(&b);
	return 0;
	return 0;
}

在这里插入图片描述

三、 什么是RTTI ?

 RTTI:Run-time Type identification的简称,即:运行时类型识别。C++通过以下方式来支持RTTI:

  1. typeid运算符
  2. dynamic_cast运算符
  3. decltype

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

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

相关文章

新手上路:在Windows CPU上安装Anaconda和PyCharm

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一. 确认自己是CPU为什么选择CPU教程&#xff1f;GPU与CPU的区别如何判断自己是CPU 二. Anaconda 安装包 和 Pycharm 安装包步骤1&#xff1a;下载Anaconda步骤2&am…

【d46】【Java】【力扣】234.回文链表

思路 判断是否是回文&#xff0c;需要&#xff1a;一个指针指向头&#xff0c;一个指针指向尾&#xff0c;两个指针一边向中间靠拢&#xff0c;一边判断数值是否相同 对于单链表&#xff0c;不方便获得pre&#xff0c;如果将节点放进 数组/list &#xff0c;数组/list可以直接…

2024年9月22日历史上的今天大事件早读

189年9月22日 &#xff08;汉灵帝中平六年八月戊辰&#xff09;大将军何进入宫&#xff0c;策划铲除宦官&#xff0c;事败被杀 1499年9月22日 瑞士独立。 1630年9月22日 明朝抗清将领袁崇焕被崇祯皇帝凌迟处死于北京 1776年9月22日 美国间谍黑尔未经审判即被处绞刑 1860年9…

buucft hashcat

使用文本编辑器打开时乱码 使用010editor打开发现时xml文档 拷贝到kali&#xff0c;使用binwalk查看&#xff0c;发现时xml文档&#xff0c;改后缀名为ppt。打开发现有密码 Accent OFFICE Password Recovery 64位-Office密码恢复软件 v20.09 免费版 - 下载吧 试试这个Accent O…

[云服务器14] 搭建属于你自己的Git服务器

Git是由Linux Torvalds开发的一个版本控制系统(VCS,Version Control System)&#xff0c;而目前最大的Git仓库托管公司就是大名鼎鼎的GitHub啦&#xff01; 而这次&#xff0c;我们主要讲在自己的服务器上&#xff0c;搭建一个GitLab驱动的Git服务器&#xff01; [请CSDN审核…

大模型的威力,远不只是聊天框

自2022年底ChatGPT发布以来&#xff0c;我们真正看到了大模型的威力&#xff0c;也引发了技术圈种种畅想。有相当一部分观点认为&#xff0c;大模型是一种工业革命级的产物&#xff0c;相信更多的人会和笔者一样&#xff0c;认为大模型是一个操作系统级的产品&#xff0c;会彻底…

基于波特图的控制系统设计算法

波特图&#xff08;Bode Plot&#xff09;是一种用于描述线性控制系统频率响应的图形表示方法&#xff0c;通常用于分析和设计控制系统。它以控制系统的传递函数&#xff08;或频域传递函数&#xff09;为基础&#xff0c;将系统的幅频特性&#xff08;振幅-频率响应&#xff0…

统信服务器操作系统【刻录镜像制作U盘启动盘的工具】

统信服务器操作系统各版本上刻录镜像制作U盘启动盘的工具方案 文章目录 应用场景一、问题现象二、问题分析解决方案应用场景 硬件/整机信息:全平台 CPU架构:全架构 OS版本信息:服务器a版,e版,d版(其中d版遇到的刻录类问题较少) 软件信息:dd工具、Fedora Media Writer工…

每日学习一个数据结构-倒排表

文章目录 示意图倒排表的基本概念倒排表的数据结构示例 倒排表的优点应用场景 倒排表&#xff08;Inverted Index&#xff09;&#xff0c;也称为反向索引或倒排文件&#xff0c;在信息检索系统中是一种重要的数据结构。它主要用于快速搜索文档中的关键词&#xff0c;并找到包含…

史上最全!!!大厂面试真题-SpringBoot自动装配的原理是什么?

我想你也在真实面试中被问过无数次这个问题了&#xff0c;我也是&#xff0c;但是不管你怎么搜&#xff0c;都只有那几篇八股文的答案&#xff0c;你问GPT它都解释不清楚&#xff0c;我决定自己写一篇详细的&#xff0c;避免遗忘也想帮助一下患难中的兄弟姐妹们&#xff0c;能把…

读取t x t文件生成exce

读取t x t文件生成excel package com.moka.api.custom.core.controller; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermode…

NLP 文本分类核心问题

解决思路 分解为多个独立二分类任务将多标签分类转化为多分类问题更换 loss 直接由模型进行多标签分类 数据稀疏问题 标注更多数据&#xff0c;核心解决方案&#xff1a; 自己构造训练样本 数据增强&#xff0c;如使用 chatGPT 来构造数据更换模型 减少数据需求增加规则弥补…

ReKep——李飞飞团队提出的让机器人具备空间智能:基于视觉语言模型GPT-4o和关系关键点约束

前言 由于工厂、车厂的任务需求场景非常明确&#xff0c;加之自今年年初以来&#xff0c;我司在机器人这个方向的持续大力度投入(包括南京、长沙两地机器人开发团队的先后组建)&#xff0c;使得近期我司七月接到了不少来自车厂/工厂的订单&#xff0c;比如其中的三个例子&…

草莓团队创造了o1 - Building OpenAI o1 (Extended Cut) 观后笔记

美妙的事物往往需要世界去创造&#xff0c;商业希望大模型越来越快给出回答。或许花费几个月几年的时间持续思考&#xff0c;大模型能够解决更复杂的问题&#xff0c;而不只是回答42 刚发现凌晨OpenAI发布了一个22多分钟的采访&#xff0c;将构建出O1的整个团队拉到一个小屋子&…

基于单片机红外感应智能卫生间系统仿真

文章目录 前言资料获取设计介绍功能介绍设计程序具体实现截图设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff0c;一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对…

基于微信小程序的智慧物业管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

设置VsCode搜索时排除文件,文件列表中隐藏文件

按照《VsCode gdb gdbserver远程调试C程序》中介绍的方法&#xff0c;配置好VsCode后&#xff0c;打开一个C/C工程&#xff0c;发现左侧的面板会显示编译时生成的中间文件&#xff08;比如.d和.o文件&#xff09;。我们可以通过设置隐藏掉一些我们不需要打开的文件以简洁面板…

Class path contains multiple SLF4J bindings.

最近由于要改kafka成datahub&#xff0c;于是在pom文件上引入了 <dependency><groupId>com.aliyun.datahub</groupId><artifactId>aliyun-sdk-datahub</artifactId><version>2.25.1</version> </dependency> 然后让我去测试…

C语言中if else组合

一 bool变量与“零值”进行比较 bool 变量与“零值”进行比较的 if 语句怎么写&#xff1f; bool bTestFlag FALSE;//想想为什么一般初始化为 FALSE 比较好&#xff1f; A), if(bTestFlag 0); if(bTestFlag 1); B), if(bTestFlag TRUE); if(bTestFlag FLASE); C), if(b…

WPF DataGrid 动态修改某一个单元格的样式

WPF DataGrid 动态修改某一个单元格的样式 <DataGrid Name"main_datagrid_display" Width"1267" Height"193" Grid.Column"1"ItemsSource"{Binding DataGridModels}"><DataGrid.Columns><!--ElementStyle 设…