【c++】强制类型转化

news2024/9/24 17:21:24

一、前言

在C++语言中新增了四个关键字static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。

新类型的强制转换可以提供更好的控制强制转换过程,允许控制各种不同种类的强制转换。

C++中风格是static_cast<type>(content)。C++风格的强制转换其他的好处是,它们能更清晰的表明它们要干什么。程序员只要扫一眼这样的代码,就能立即知道一个强制转换的目的。

二、static_case

static_case:静态转换是最常用的一种类型转换,它可以在不同但相关的类型之间进行转换,如基本数据类型之间的转换、父类指针向子类指针的转换等。但是需要注意的是,静态转换没有运行时类型检查,因此在进行转换时需要确保类型之间是相关的,否则可能会导致错误。

int a = 10;
int b = 3;
double result = (double)a / (double)b;

它主要有如下几种用法:

  • 用于类层次结构中基类和派生类之间指针或引用的转换
  • 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的
  • 进行下行转换(把基类的指针或引用转换为派生类表示),由于没有动态类型检查,所以是不安全的
  • 用于基本数据类型之间的转换,如把int转换成char。这种转换的安全也要开发人员来保证
  • 把空指针转换成目标类型的空指针
  • 把任何类型的表达式转换为void类型
  • 注意:static_cast不能转换掉expression的const、volitale或者__unaligned属性。

static_cast:可以实现C++中内置基本数据类型之间的相互转换。

如果涉及到类的话,static_cast只能在有相互联系的类型中进行相互转换,不一定包含虚函数。

三、const_cast

在C语言中,const限定符通常被用来限定变量,用于表示该变量的值不能被修改。

而const_cast则正是用于强制去掉这种不能被修改的常数特性,但需要特别注意的是const_cast不是用于去除变量的常量性,而是去除指向常数对象的指针或引用的常量性,其去除常量性的对象必须为指针或引用。

示例代码:

const int a = 100;
int* p = const_cast<int*>(&a);
*p = 200;

cout << *p << endl;
cout << a << endl;

运行截图:

在上面的例子中,用p指向常量a,并且用const_cast去除p指针的常性,再对p指针解引用进行赋值,发现p中存放的值是被改变,但是a的值还是没有改变。

为什么相同的地址,*p的值改变了,但是a的值没有改变?

其实这是一件好事,我们要庆幸a变量最终的值没有变成200!变量a一开始就被声明为一个常量变量,不管后面的程序怎么处理,它就是一个常量,就是不会变化的。一旦一个项目工程非常庞大的时候,在程序某个地方出现了一个p这样的指针,它可以修改常量a,这是一件很可怕的事情的,可以说是一个程序的漏洞,毕竟将变量a声明为常量就是不希望修改它,如果后面能修改,这就太恐怖了。

如果加上volatile呢?

volatile const int a = 100;
int* p = const_cast<int*>(&a);
*p = 200;

cout << *p << endl;
cout << a << endl;

如果不加volatile,a就没有被修改,因为编译器做出的优化,将const修饰的a的值直接存放到寄存器当中,或者直接将a替换成2,加了volatile就会去内存当中寻找a的值,就能修改。

四、reinterpret_cast

在C++语言中,reinterpret_cast主要有三种强制转换用途:改变指针或引用的类型、将指针或引用转换为一个足够长度的整形、将整型转换为指针或引用类型

//reinterpret_cast 不相近类型之间的转换
int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;//12
	//int *p = static_cast<int*>(&a);这里使用static_cast会报错,应该使用reinterpret_cast
	int* p = reinterpret_cast<int*>(&a);
    cout << *p << endl;//12
	return 0;
}

在使用reinterpret_cast强制转换过程仅仅只是比特位的拷贝,这种转换的结果会导致实际编程中的指针指向的内容是不明确的,因此需要开发者自行确保转换的安全性,谨慎使用。

五、dynamic_cast

  1. 以上三种强制类型转化都是编译时完成的,dynamic_cast是在运行时处理的,运行时要进行类型检查
  2. 不能用于基本数据类型的强制转换,一般是用于父类指针或者引用向子类指针或者引用进行类型转换。
  3. 如果转化成功的话,返回指向类的指针或者引用,如果转化失败的话,是返回NULL。
  4. 要使用dynamic_cast进行转化,基类一定要有虚函数,否则编译不通过。因为只有当类中存在虚函数,就说明它有想让基类指针或者引用指向派生类对象的情况,此时进行了类型转换才有意义。运行时类型检查需要运行时类型信息,这个信息保存在虚函数表当中。
  5. 相比static_cast,上行转换的效果一致,但下行转换时,dynamic_cast多了类型检查,比static_cast更加安全。
#include <iostream>
 
class Base {
public:
    virtual ~Base() {}
};
 
class Derived : public Base {
public:
    void DerivedMethod() {
        std::cout << "Derived method called." << std::endl;
    }
};
 
int main() {
    Base* da = new Derived;
    Derived* db = dynamic_cast<Derived*>(da);
    if (db) {
        db->DerivedMethod();
    }
    else {
        std::cout << "dynamic_cast failed." << std::endl;
    }
 
    delete da;
    return 0;
}

结果:

Derived method called.

如果父类指针本来指向父类对象,被类型转化为子类指针,如果强制转换,那么会存在越界访问的问题,此时如果用dynamic_cast进行转换,那么会得到一个空指针,如果这个父类指针指向子类对象,转化为子类指针,不存在安全问题,所以此时用dynamic_cast转换就是安全的。

注意:父类必须包含虚函数,要不然dynamic_cast就不能用了。

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

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

相关文章

进阶SpringBoot之 SpringSecurity(2)用户认证和授权

Spring Security 官网 Spring Security 是针对 Spring 项目的安全框架 也是 Spring Boot 底层安全模块默认的技术选型 它可以实现强大的 Web 安全控制 只需引入 spring-boot-starter-security 模块&#xff0c;进行少量配置&#xff0c;即可实现强大的安全管理 几个重要的…

首款国产“3A”游戏《黑神话:悟空》爆火,背后有哪些AI技术在助力?

近日&#xff0c;沉淀了4年的首款国产“3A”游戏《黑神话悟空》正式在各大游戏交易平台上线。 据市场研究公司VG Insights 周四晚间发布预估数据&#xff0c;《黑神话&#xff1a;悟空》自发售以来&#xff0c;三天内在 Steam 平台的销量已突破 840 万份&#xff0c;好评率超 …

速腾32线激光雷达使用方法

速腾32线激光雷达 12V电源 实体机ubuntu22.04 ROS2-humble 一、软件安装 mkdir robosense_ws cd robosense_wsmkdir src && cd src/ git clone https://github.com/RoboSense-LiDAR/rslidar_msg.git git clone https://github.com/RoboSense-LiDAR/rslidar_sdk.gi…

数学基础(六)

一、分布 正态分布 二项式分布 均匀分布 卡方分布 二、核函数 核函数的目的&#xff1a; 将低维数据转换为高维数据 线性核函数&#xff1a; Linear核函数对数据不做任何变换 当特征已经比较丰富了&#xff0c;样本数据量巨大&#xff0c;需要进行实时得出结果时进行使用…

【GH】【EXCEL】P3: Set Conditional Formatting To Excel Data By Gh

文章目录 conditional formattingdata sourceConditional ScaleConditional Scale Conditional PercentConditional Top Percent Conditional AverageConditional Average Multiple ConditionsConditional BarConditional Bar Conditional UniqueConditional Unique Conditiona…

JUC7-共享模型之工具

线程池 自定义线程池 import lombok.extern.slf4j.Slf4j; import org.springframework.core.log.LogDelegateFactory;import java.util.ArrayDeque; import java.util.Deque; import java.util.HashSet; import java.util.concurrent.TimeUnit; import java.util.concurrent.l…

git常用操作合集

1 撤销 1.1 适用场景 如果在git上提交了commit&#xff0c;但是当前提交的代码有问题&#xff0c;需要回退到上个版本 1.2 操作命令 1、git log 查看历史提交记录及对应的commit id 找到需要回退的commit id 2、执行git reset回退到之前的状态 git reset --hard <commi…

BaseCTF [第一周]Ez Xor

笔记。 64ida打开。 走&#xff01; 逆向逆向&#xff0c;逆向往前看。 因为异或算法&#xff0c;A ^BC >>> C^BA 所以在只需要知道密钥key就可以了。 是不是头大&#xff1f; 没事 这里介绍另一种方法>>> IDA 动态调试去获取key值、密文值 。(灵活使用工…

编写程序调用元神操作系统的API

1. 背景 本文介绍了元神操作系统API的调用&#xff0c;并详细介绍了“调用元神系统API读取磁盘扇区”程序的编写以及测试结果。 2. 方法 &#xff08;1&#xff09;元神操作系统API的调用方法 元神操作系统0.4版beta4开始提供了对OS功能的调用&#xff0c;调用相关的定义如…

整形提升

有任何不懂的问题可以评论区留言&#xff0c;能力范围内都会一一回答 整型提升 (Integral Promotion)是指在计算机编程中&#xff0c;当不同类型的整数类型进行运算时&#xff0c;较小类型的整数会被自动转换为更大类型的整数&#xff0c;以确保运算的正确进行。这种类型转换主…

【生日视频制作】公司前台接待文化形象墙字写字楼办公室AE模板修改文字软件生成器教程特效素材【AE模板】

公司前台形象墙写字楼办公室生日视频制作教程AE模板修改文字素 怎么如何做的【生日视频制作】公司前台接待文化形象墙字写字楼办公室AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤&#xff1a; 安装AE软件下载AE模板把AE模板导入AE软件修改图片或文字渲染…

STM32寄存器操作、模板构建

目录 外设寄存器查找 ① 名称② 偏移地址③ 寄存器位表④ 位功能说明寄存器基本操作 C语言的置位和清零 具体方法设置GPIO流程给寄存器赋值带参数宏STM32F1xx 芯片识别存储器映射寄存器映射让GPIOB端口的16个引脚输出高电平&#xff0c;要怎么实现&#xff1f;STM32寄存器映射…

探索大语言模型在DNA 分析到表达预测以及生物信息学应用

概述 论文地址&#xff1a;https://arxiv.org/abs/2401.04155 随着 OpenAI 的 GPT-X 和谷歌的 BERT 等大规模语言模型的出现&#xff0c;自然语言处理领域得到了飞速发展。这些先进的模型将理解和生成人类语言的能力发挥到了极致&#xff0c;彻底改变了日常交流和业务流程。 …

premiere2023暴力压缩视频

目录 1. 需求说明2. 压缩流程 1. 需求说明 要将三段视频拼接起来&#xff0c;时长超过了1h&#xff0c;然后压缩到200M以内的视频。 这是三段视频的信息&#xff1a; 合并三个视频文件意味着总时长增加了。较长的视频文件通常也会更大&#xff0c;即使比特率相同。 当我把三段…

分治算法的介绍与原理解析

文章目录 1.分治算法1.1 如何判断分治问题1.2 为什么通过分治可以提升效率1.2.1 操作数量的优化1.2.2 并行计算优化 1.3 分治常见应用 1.分治算法 分治&#xff08;divide and conquer&#xff09;&#xff0c;全称是分而治之&#xff0c;是一种非常重要且非常常见的算法。分治…

【SQL基础】【牛客网】子查询、联表查询

子查询 基本语法 子查询&#xff0c;也称为嵌套查询&#xff0c;是在另一个 SQL 语句中嵌套的查询。子查询的结果可以被主查询&#xff08;外部查询&#xff09;使用&#xff0c;用于满足更复杂的数据检索需求。 例如&#xff1a; SELECT employee_name FROM employees WHE…

优化的热点分析与异常值分析:让数据分析更加便捷高效

热点分析作为一种常用的空间统计方法&#xff0c;能够帮助我们识别地理空间中的热点和冷点区域&#xff0c;即那些高值或低值集中出现的地方。而优化的热点分析进一步简化了这一过程&#xff0c;使用户无需手动调整参数即可获得可靠的结果。此外&#xff0c;异常值分析则专注于…

学习记录——day35 数据库 sqlite3

目录 一、安装sqlite3数据库以及sqlite3函数库 二、数据库的结构 三、常用数据库类型 1、sqlite3 2、mysql 四、sqlite3数据库的使用 1、打开数据库 2、sqlite3数据库中指令的使用 1&#xff09;界面指令 2&#xff09;操作指令 3&#xff09;大小写敏感性 3、创建表…

基于STM32开发的智能家居灯光控制系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化灯光控制逻辑传感器数据采集Wi-Fi通信与远程控制应用场景 家庭智能灯光管理办公室与商业环境的智能照明常见问题及解决方案 常见问题解决方案结论 1. 引言 随着智能家居技术的普及…

尚品汇-购物车列表、临时用户购物车与登录用户购物车合并实现(三十七)

目录&#xff1a; &#xff08;1&#xff09;功能—展示购物车列表 &#xff08;2&#xff09;在web-all添加前端实现 &#xff08;3&#xff09;功能--合并购物车 &#xff08;1&#xff09;功能—展示购物车列表 购物车列表接口&#xff1a;CartService /*** 通过用户Id …