C++ 4种类型转换运算符

    C语言中的强制转换在C++中对基础数据类型也是适用的,但是对于类对象就不够严格。于是C++中增加了4种类型转换运算符,使得转换过程更规范:
dynamic_cast;
const_cast;
static_cast;
reinterpret_cast;

1、dynamic_cast动态类型转换
    dynamic_cast是运行时的类型转换,可在基类和派生类之间进行类型转换,并且能够检查类型是否符合转换。它不能回答“指针指向的是哪类对象”的问题,但可以回答“是否可以安全地将对象的地址赋给特定类型的指针”的问题。 dynamic_cast运算符的语法如下:

dynamic_cast< type-name > (expression);

    该运算符的用途是,使得能够在类层次结构中进行向上转换(由于is-a关系,这样的类转换是安全的),而不允许其他转换。
假设High和Low是两个类,而ph和pl是的类型是High * 和 Low ,则仅当Low是High的可访问基类(直接或间接)时,下面的语句才将一个Low 指针赋给pl:

pl = dynamic_cast<Low *>ph;//派生类指针通过dynamic_cast转为基类指针赋给基类指针;

如果Low不是High的可访问基类,上述语句将空指针赋给pl

2、const_cast
    const_cast运算符用于执行只有一种用途的类型转换,及改变值为const或volatitle,其语法与dynamic_cast运算符相同

const_cast < type-name > (expression)

    如果类型的其他方面也被修改,则上述类型转换将出错。也就是说,除了const 或volatitle特征(或有无)可以不同,type-name和expression的类型必须相同。再次假设High和Low是两个类:

High bar;
const High * pbar = &bar;
...
High * pb = const_cast< High * >pbar;//valid   type-name和expression只是const属性不同
const Low * pl = const_cast< Low * >(pbar);//invalid  type-name为Low*;expression为const High *

const_cast不是万能的。它可以修改执行一个值的指针,但修改const值的结果是不确定的。

3、static_cast:静态类型转换
    static_cast是在编译时进行类型转换,只能用于已知的类型之间的转换。主要用于基本数据类型的转换、隐式转换的显式化和向上转换(子类指针或引用转为父类指针或引用)。static_cast运算符的语法与其他类型转换运算符相同:

static_cast < type-name > (expression);

    仅当type-name 可被隐式转换为expression所属的类型或expression可被隐式转换为type-name所属的类型时,上述转换才合法。 假设High是Low的基类,而Pond是一个无关的类,则从High类到Low类的转换,从Low到High的转换都是合法的,而从Low到Pond的转换是不允许的。

High bar;
Low blow;
...
High * pb = static_cast< High * >(&blow);//valid upcast
Low * pl = static_cast< Low * >( &bar);//valid downcast
Pond *pmer = static_cast< Pond *>(&blow);//invalid, Pond unrelated

    第一种转换是合法的,因为向上的转化可以显式的进行。第二种转换是从基类指针到派生类指针,在不进行显式转换的情况下,将无法进行。
4、reinterpret_cast
    reinterpret_cast运算符用于天生危险的类型转换。它不允许删除const,但会执行其他令人生厌的操作。语法与另外3个相同:

reinterpret_cast< type-name >(expression);

下面是一个使用示例:

struct dat{short a; short b;};
long value = 0xA224B118;
dat * pd = reinterpret_cast< dat * >(&value);
cout<<hex<< pd->a;//display first 2 bytes of value

    通常这样的转换适用于依赖于实现的底层技术,是不可移植。例如,在不同系统在存储多字节整型时,可能以不同的顺序存储其中的字节。
    然而,reinterpret_cast运算符并不支持所有的类型准换。例如,可以将指针类型转换为足以存储指针表示的整型,但不能将指针转换为更小的整型或浮点型。另一个限制是,不能将函数指针转换为数据指针。

总结:
1、派生类指针或引用可以直接赋给基类指针(可以理解为把派生类切割了赋给基类),也可以使用static_cast对指针进行转换。
2、基类指针或引用可以使用dynamic_cast,或static_cast转换为派生类指针或引用。
3、static_cast可以用于基本类型之间的转换,dynamic_cast不可以
4、static_cast可以在基本类型指针与void *之间做转换,dynamic_cast
5、static_cast和dynamic_cast都不能在基本类型指针或引用剪做转换
6、const_cast运算符主要用于增加或减少指针的const修饰,指针指向的内容为非const,则可以用指针修改指向的内容;如果指针指向的内容本身就是const值,通过指针方式也不能修改指向的内容。
7、reinterpret_cast可以将指针类型转换为足以存储指针表示的整型,但不能转换为更小的整型或浮点型(转换为不足以存储指针表示的整型的行为是不允许的);不能将函数指针转换为数据指针。
注:使用dynamic_cast转换后一定要对指针判空。指针为空,表示转换失败;指针非空,表示转换成功。

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

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

相关文章

【SysBench】Linux 安装 sysbench-1.20

安装目的是为了对 MySQL 8.0.x 、PostgreSQL 进行基准测试。 0、sysbench 简介 sysbench 是一个可编写脚本的多线程基准测试工具&#xff0c;基于 LuaJIT 。 它最常用于数据库基准测试&#xff0c;但也可以 用于创建任意不涉及数据库服务器的复杂工作负载。 sysbench 附带以…

【诚信3·15】广州流辰信息|诚信至上,始终如一!

每一个承诺&#xff0c;广州流辰信息皆倾心对待&#xff1b;每一份期待&#xff0c;广州流辰信息亦用心守护。近十年用专业缔造好品质&#xff0c;用服务追求好口碑。在为客户服务的路上&#xff0c;流辰信息始终无惧考验&#xff0c;保持初心。在3.15国际消费者权益日&#xf…

SpringBoot3学习记录(有ssm基础)

目录 一、SpringBoot3 介绍 SpringBoot3 简介 SpringBoot3 快速入门 入门总结 1.为什么依赖不需要写版本 2.Startrer&#xff08;启动器&#xff09;是什么 3.SpringBootApplication 二、SpringBoot3 配置文件 统一配置管理 使用yaml配置文件&#xff08;推荐&#x…

Seatunnel系列之:部署Seatunnel

Seatunnel系列之&#xff1a;部署Seatunnel 一、步骤一&#xff1a;准备环境二、步骤二&#xff1a;下载SeaTunnel三、步骤三&#xff1a;安装连接器插件四、quick-start-seatunnel-engine1.添加作业配置文件来定义作业2.运行 SeaTunnel 应用程序 五、quick-start-flink1.部署和…

Gateway网关在url参数带有特殊字符的情况下转发失败(响应400)

本文主要分享了&#xff0c;SpringCloud Gateway网关在url参数带有空格或者特殊字符的情况下&#xff0c;转发失败导致响应错误码400的解决方案。 响应400错误码的2种场景&#xff1a; 1.参数带空格&#xff0c;Gateway会误认为该空格是切割符&#xff0c;如?phone 135****6…

QT使用dumpcpp为COM生成h及cpp的方式,COM是C#的dll注册的

目录 1.C#的dll注册为COM&#xff0c;采用bat的方式 2.通过qt的dumpcpp来生成h及cpp文件 3.h文件和cpp文件处理。 台达数控系统的C#的dll dumpcpp用的tlb文件 dumpcpp生成的原生h文件 dumpcpp生成的原生cpp dump生成后的的原生cpp文件修改后的cpp文资源 dump生成后的的…

AI短视频矩阵系统介绍|罐头鱼AI视频批量生成

智能化管理&#xff0c;轻松批量剪辑短视频&#xff01; 近年来&#xff0c;随着短视频营销行业的发展&#xff0c;我们推出了一款AI短视频矩阵系统&#xff0c;旨在帮助用户管理、剪辑和发布短视频内容&#xff0c;从而提升品牌影响力。让我们来看看这款系统都提供了哪些功能&…

C:数据结构王道

初始化顺序表&#xff08;顺序表中元素为整型&#xff09;&#xff0c;里边的元素是1,2,3&#xff0c;然后通过scanf读取一个元素&#xff08;假如插入的是6&#xff09;&#xff0c;插入到第2个位置&#xff0c;打印输出顺序表&#xff0c;每个元素占3个空格&#xff0c;格式为…

在哪些领域中最需要使用 OCR 识别技术?

光学字符识别&#xff08;OCR&#xff09;技术能够将不同格式的印刷或手写文本转换为机器编码的文本&#xff0c;这一技术在许多领域都发挥着重要作用&#xff0c;尤其是在需要大量处理文档和图像数据的场景中。以下是一些最需要使用OCR识别技术的领域&#xff1a; 1. 办公自动…

Windows Server 各版本搭建终端服务器实现远程访问(03~19)

一、Windows Server 2003 左下角开始➡管理工具➡管理您的服务器&#xff0c;点击添加或删除角色 点击下一步 勾选自定义&#xff0c;点击下一步 点击终端服务器&#xff0c;点击下一步 点击确定 重新登录后点击确定 点击开始➡管理工具➡计算机管理&#xff0c;展开本地用户…

openssl3.2 - 官方demo学习 - encode - ec_encode.c

文章目录 openssl3.2 - 官方demo学习 - encode - ec_encode.c概述笔记产生ecc私钥产生ecc公钥测试工程备注备注END openssl3.2 - 官方demo学习 - encode - ec_encode.c 概述 官方demos/encode 目录中给了2个例子工程 功能是载入(RSA/ECC)公钥, 然后自己就可以拿内存中的公钥对…

mupdf渲染过程(一):颜色

mupdf除了解析PDF功能之外&#xff0c;还有一个强大的功能就是渲染文字和图像&#xff0c;本文介绍mupdf渲染过程中涉及到的颜色问题&#xff1a;包括颜色空间&#xff0c;颜色转换&#xff0c;lcms的使用。 1.初始化 mupdf初始化第一步是实例化fz_context *ctx&#xff0c;fz…

利用适配器模式使用第三方库

文章目录 一、为什么要使用适配器模式二、适配器模式使用第三方库示例 一、为什么要使用适配器模式 适配器模式是一种设计模式&#xff0c;用于将一个类的接口转换成客户端所期望的另一个接口。适配器模式的主要目的是使不兼容的接口能够一起工作。以下是一些使用适配器的原因&…

OpenCV开发笔记(七十七):相机标定(二):通过棋盘标定计算相机内参矩阵矫正畸变摄像头图像

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/136616551 各位读者&#xff0c;知识无穷而人力有穷&#xff0c;要么改需求&#xff0c;要么找专业人士&#xff0c;要么自己研究 红胖子(红模仿)的博…

TypeScript的基础类型和高级类型梳理总结

一、基础类型 1、boolean 布尔类型 表示逻辑值&#xff0c;可以是 true 或 false let isBoolean:boolean false 2、number 数字类型 表示整数和浮点数&#xff08;例如 42&#xff0c;3.14159&#xff09;&#xff0c;不论是十进制、二进制、八进制还是十六进制&#xff…

Rust镜像配置

cargo镜像配置 找到.cargo目录并创建config文件,输入以下内容即可,windows一般在C:\Users\用户目录\.cargo,linux执行vim ~/.cargo/config即可。然后将下面内容赋值粘贴进去 [source.crates-io] registry = "https://github.com/rust-lang/crates.io-index" rep…

Visual Studio 2022 配置“Debug|x64”的 Designtime 生成失败。IntelliSense 可能不可用。

今天写代码&#xff0c;无缘无故就给我整个这个错误出来&#xff0c;我一头雾水。 经过我几个小时的奋战&#xff0c;终于解决问题 原因就是这个Q_INTERFACES(&#xff09;宏&#xff0c;我本想使用Q_DECLARE_INTERFACE Q_INTERFACES这两个Qt宏实现不继承QObject也能使用qobjec…

C语言自学笔记17----结构体struct与位域与关键字typedef

C 语言结构体(struct) 为什么在C中使用结构&#xff1f; 假设您要存储有关一个人的信息&#xff1a;他/她的姓名&#xff0c;身份证号和薪水。您可以创建不同的变量name&#xff0c;citNo和salary存储此信息。 如果您需要存储多个人的信息怎么办&#xff1f;现在&#xff0c;你…

VSCode提交代码

VSCode提交代码方式&#xff1a; 先在电脑本地文件夹中打开git的bash窗口使用git clone https://github.com/xxxx/克隆仓库地址到本地&#xff0c;并生成一个项目的文件夹打开VSCode&#xff0c;点击文件按钮&#xff0c;打开加载项目的文件夹对于VSCode设置Git路径&#xff…

Three 材质纹理 (总结三)

THREE.MeshLambertMaterial&#xff08;网格 Lambert 材质&#xff09; 该材质使用基于非物理的Lambertian模型来计算反射率。可以用来创建暗淡的并不光亮的表面&#xff0c;该材质非常易用&#xff0c;而且会与场景中的光源产生反应。 MeshLambertMaterial属性 # .color : …