类型转换C11

news2025/1/12 21:36:11

类型转换

C++类型转换分为显式类型转换和隐式类型转换 ,隐式类型转换由编译器自动完成,这里只讨论显式类型转换。

旧式风格的类型转换

type(expr); // 函数形式的强制类型转换
(type)expr; // C语言风格的强制类型转换

现代C++风格的类型转换

cast-name<type>(expression)

type是转换的目标类型。

expression是被转换的值。

cast-name有static_cast,dynamic_cast,const_cast和reinterpret_cast四种,表示转换的方式。

static_cast

格式:

static_cast<type>(expression)

任何编写程序时能够明确的类型转换都可以使用static_cast(static_cast不能转换掉底层const,volatile和__unaligned属性)。由于不提供运行时的检查,所以叫static_cast,因此,需要在编写程序时确认转换的安全性。

主要在以下几种场合中使用:

  1. 用于类层次结构中,父类和子类之间指针和引用的转换;进行上行转换,把子类对象的指针/引用转换为父类指针/引用,这种转换是安全的;进行下行转换,把父类对象的指针/引用转换成子类指针/引用,这种转换是不安全的,需要编写程序时来确认;
  2. 用于基本数据类型之间的转换,例如把int转char,int转enum等,需要编写程序时来确认安全性;
  3. 把void指针转换成目标类型的指针(这是极其不安全的);

示例:

int i, j;
double slope = static_cast<double>(j) / i;
void *p = &d;
double *dp = static_cast<double*>(p);

dynamic_cast

格式:

dynamic_cast<type>(expression)

相比static_cast,dynamic_cast会在运行时检查类型转换是否合法,具有一定的安全性。由于运行时的检查,所以会额外消耗一些性能。dynamic_cast使用场景与static相似,在类层次结构中使用时,上行转换和static_cast没有区别,都是安全的;下行转换时,dynamic_cast会检查转换的类型,相比static_cast更安全。

dynamic_cast转换仅适用于指针或引用。

在转换可能发生的前提下,dynamic_cast会尝试转换,若指针转换失败,则返回空指针,若引用转换失败,则抛出异常。

1.继承中的转换

(1)上行转换:

在继承关系中 ,dynamic_cast由子类向父类的转换与static_cast和隐式转换一样,都是非常安全的。

(2)下行转换

class A { virtual void f(){}; };
class B : public A{ };
void main()
{
     A* pA = new B;
     B* pB = dynamic_cast<B*>(pA); 
}

注意类A和类B中定义了一个虚函数,这是不可缺少的。因为类中存在虚函数,说明它可能有子类,这样才有类型转换的情况发生,由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。

2.void*的转换

一些情况下,我们需要将指针转换为void*,然后再合适的时候重新将void*转换为目标类型指针。

class A { virtual void f(){} };
int main()
{
     A *pA = new A;
     void *pV = dynamic_cast<void *>(pA); 
}

3.菱形继承中的上行转换

首先,定义一组菱形继承的类:

class A { virtual void f() {}; };
class B :public A { void f() {}; };
class C :public A { void f() {}; };
class D :public B, public C { void f() {}; };

继承关系如图:

image-20221117225713058

B继承A,C继承A。

D继承B和C。

考虑这样的情况:D对象指针能否安全的转换为A类型指针?

直觉来说是可以的,因为从子类向父类转化,无论如何都是安全的。

class A { virtual void f() {}; };
class B :public A { void f() {}; };
class C :public A { void f() {}; };
class D :public B, public C { virtual void f() {}; };

void main()
{
    D *pD = new D;
    A *pA = dynamic_cast<A *>(pD); // pA = NULL
}

但实际上,如果尝试这样的转换,只能得到一个空指针。因为B和C都继承了A,并且都实现了虚函数f(),导致在进行转换时,无法选择一条转换路径。

一种可行的方法是,自行指定一条转换路径:

class A { virtual void f() {}; };
class B :public A { void f() {}; };
class C :public A { void f() {}; };
class D :public B, public C { void f() {}; };

void main()
{
    D *pD = new D;
    B *pB = dynamic_cast<B *>(pD);
    A *pA = dynamic_cast<A *>(pB);
}

const_cast

格式:

const_cast<type>(expression)

const_cast用于移除类型的const、volatile和__unaligned属性。

常量指针被转换成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然引用原来的对象。

const char *pc;
char *p = const_cast<char*>(pc);

reinterpret_cast

格式:

reinterpret_cast<type>(expression)

非常激进的指针类型转换,在编译期完成,可以转换任何类型的指针,所以极不安全。非极端情况不要使用。

int *ip;
char *pc = reinterpret_cast<char*>(ip);
erpret_cast**

格式:

```cpp
reinterpret_cast<type>(expression)

非常激进的指针类型转换,在编译期完成,可以转换任何类型的指针,所以极不安全。非极端情况不要使用。

int *ip;
char *pc = reinterpret_cast<char*>(ip);

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

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

相关文章

1-2 VMware安装Rocky9.0和Ubuntu22.04系统

文章目录前言下载链接VMware使用安装Rocky9.0系统Rocky初始化安装Ubuntu22.04系统Ubuntu初始化VMware快照前言 VMware虚拟机软件是一个“虚拟PC”软件&#xff0c;它使你可以在一台机器上同时运行二个或更多Windows、DOS、LINUX系统。 Rocky Linux 9.0 操作系统与2022年7月14…

基于matlab GUI的数字图像处理系统

目 录 摘 要 I Abstract II 第1章 绪论 1 1.1选题背景及意义 1 1.2国内外研究现状 2 1.2.1国内研究现状 2 1.2.2国外研究现状 3 1.3研究主要内容 3 第2章 数字图像处理系统设计 5 2.1设计概括 5 2.2文件 6 2.2.1打开 6 2.2.2保存 6 2.2.3退出 6 2.3图像变形 7 2.3.1图像缩放 7 …

Spring Cloud Gateway 使用示例

Spring Cloud Gateway 使用示例 作者&#xff1a; Grey 原文地址&#xff1a; 博客园&#xff1a;Spring Cloud Gateway 使用示例 CSDN&#xff1a;Spring Cloud Gateway 使用示例 说明 Spring Cloud Gateway 用于构建 API 网关&#xff0c;基于 Spring WebFlux。 在Spr…

【雷达通信】回波数据处理(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

【VRP问题】基于蚁群算法求解配送路径最短问题附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

静态成员函数与回调函数

1. 静态成员函数 1.1 静态成员函数调用 如何代码块里的函数get_object_count是静态成员函数&#xff0c;对静态成员函数无论是通过类名还是通过对象或对象指针调用&#xff0c;最终都会被编译器转换为全局非成员函数的调用。例如obj.get_object_count()或Point3d::get_object…

BigDecimal精度丢失问题

浅谈BigDecimal精度丢失问题 文章目录浅谈BigDecimal精度丢失问题一. 简介二. 错误使用三. 原因分析四. 正确使用一. 简介 ​ Java在java.math包中提供的API类BigDecimal&#xff0c;用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数&#…

大数据Kudu(二):Kudu架构

文章目录 Kudu架构 一、​​​​​​​Kudu存储模型及概念 二、​​​​​​​​​​​​​​Kudu table存储原理 Kudu架构 一、​​​​​​​Kudu存储模型及概念 Kudu有自己的数据存储模型&#xff0c;不依赖于HDFS、Hive、HBase其他大数据组件。Kudu有自己的集群&#…

Oracle存储过程入门教程(通俗理解存储过程)

Oracle存储过程入门通俗介绍一、存储过程通俗理解二、创建存储过程基本语法(汇总)三、执行存储过程的方式&#xff08;5种&#xff09;四、网上现有的创建存储过程的两种方式解释&#xff08;看注释&#xff09;五、一些存储过程示例&#xff08;仅供参考&#xff09;六、其他语…

蒸馏+Distilling Knowledge via Knowledge Review论文笔记

文章目录一、前言二、蒸馏1.背景介绍2.知识蒸馏和迁移学习之间的区别3.Hinton提出的知识蒸馏Pipeline4.蒸馏的知识形式5.知识蒸馏的方法三、Distilling Knowledge via Knowledge Review论文笔记1.思想介绍2.Pipeline3.实验结果参考文献一、前言 近期在阅读cvpr 2021的一篇关于蒸…

通过Tomcat / Small Tomcat,如何部署Servlet?(超详细)

目录 基于Tomcat对Servlet进行部署 一、创建项目 二、引入Servlet依赖 三、构建目录结构 四、编写代码 五、打包程序 六、部署程序 七、验证程序 基于Smart Tomcat对Servlet进行部署 第一步&#xff1a;下载Smart Tomcat插件 第二步&#xff1a;进行相关配置 第三步…

【Unity3D】选中物体描边特效

1 前言 描边的难点在于如何检测和识别边缘&#xff0c;当前实现描边特效的方法主要有以下几种&#xff1a; 1&#xff09;基于顶点膨胀的描边方法 在 SubShader 中开 2 个 Pass 渲染通道&#xff0c;第一个 Pass 通道渲染膨胀的顶点&#xff0c;即将顶点坐标沿着法线方向向外扩…

Android BLE HIDS Data ,从问询DB 到写入Android 节点的flow 之一

BLE 的HIDS服务&#xff0c;可以理解为BR/EDR HID在BLE 上的简化版&#xff0c;因BLE的特殊性&#xff0c;BR/EDR HID的部分feature在HIDS 中被移除。 本文将讨论Android 蓝牙BLE 中HIDS 服务如何接收 Data 并写入到Android 节点"/dev/uhid"的flow。----关于Android…

openpowerlink 01

源码地址&#xff1a; https://sourceforge.net/projects/openpowerlink/ 源码目录 qt 源码目录 qt MN 源码 MN是主站的意思 用cmake 构建 qt cmakelists.txt分析 文件 mnobd.cdc&#xff1a; 此文件用于配置 MN 堆栈。它包括MN和所有CN的所有配置数据&#xff0c;包括网…

云安全解决方案安全保障体系框架

安全需求和挑战 从风险管理 的角度讲&#xff0c;主要就是管理资产、威胁、脆弱性和防护措施及其相关关系&#xff0c;最终保障云计算平台的持续安全&#xff0c;以及 其所支撑的业务的安全。 云计算 平台是在传统 IT技术的基础上&#xff0c;增加了一个虚拟化层&#xff0c;并…

[Spring MVC7] 解决Redis乱码前缀问题

最近在做Redis缓存的时候&#xff0c;遇到了一个棘手的问题&#xff0c;简单来说就是项目使用Spring的RedisTemplate进行Redis数据存取操作&#xff0c;实际应用中发现Redis中key和value会出现“无意义”乱码前缀。如果是普通的java程序是没有这个问题。 本文解决Redis乱码问题…

基于Matlab-gui信号系统设计

目 录 1绪论 - 1 - 2系统分析和开发软件概述 - 6 - 2.1 需求分析 - 6 - 2.2系统开发环境和运行环境 - 6 - 2.3 Matlab图形用户界面(GUI) - 6 - 2.4 系统主要目标及功能 - 7 - 2.4.1 系统目标 - 7 - 2.4.2 系统主要功能 - 8 - 3系统软件平台的设计 10 3.1系统整体框图 10 3.2系统…

阿里的三个「价值支点」

历史总是轮回的。 2015年5月&#xff0c;身处低谷的阿里换了掌舵人&#xff0c;张勇由COO升任CEO&#xff0c;随后进行了一轮组织架构调整&#xff0c;并通过新零售、淘宝直播、阿里云等业态为阿里安上未来发展引擎。 当时的阿里市值涨至2000亿美元左右&#xff0c;华尔街投资…

终端天线—11.NFC线圈仿真

NFC线圈单体仿真 NFC线圈主要根据终端设备预留的空间大小&#xff0c;去设计走线宽度和圈数以及面积&#xff0c;NFC单体主要关注其13.56MHz处的电感量大小&#xff0c;以及阻抗的虚部和实部&#xff0c;可以根据ST和NXP芯片的要求去设计。 一、Original model 1.Simulation …

C语言文件操作【详解】

本期介绍&#x1f356; 主要介绍&#xff1a;为什么使用文件&#xff0c;什么是文件&#xff0c;文件的打开和关闭的操作方法&#xff0c;文件的顺序读写于随机读写&#xff0c;文件读取结束的判定&#x1f440;。 文章目录一、为什么使用文件&#x1f356;二、什么是文件&…