当前位置: 首页 > news >正文

C++基础 强制转换

目录

static_cast:static_cast(expression)

const_cast

dynamic_cast

reinterpret_cast


C++ 提供以下几类转换

static_cast:static_cast<type-id>(expression)

tatic_cast 主要用于以下几种情况:

  1. 用于显式地将一个表达式转换为另一种类型,包括基本类型、指针类型和引用类型。
  2. 用于将基类指针或引用转换为派生类指针或引用(向下转型)。
  3. 用于将 void* 指针转换为任意类型的指针。
  4. 用于将任意类型的指针转换为 void* 指针。

需要注意的是tatic_cast 不会在运行时检查该对象的运行时类型,安全的向下转换可以用dynamic_cast 执行

示例

#include <vector>
#include <iostream>struct B
{int m = 0;void hello() const{std::cout << "Hello world,这里是 B!\n";}
};struct D : B
{void hello() const{std::cout << "Hello world,这里是 D!\n";}
};enum class E { ONE = 1, TWO, THREE };
enum EU { ONE = 1, TWO, THREE };int main()
{// 1: 静态向下转型D d;B& br = d; // 通过隐式转换向上转型br.hello();D& another_d = static_cast<D&>(br); // 向下转型another_d.hello();// 2: 左值到右值std::vector<int> v2 = static_cast<std::vector<int>&&>(v);std::cout << "移动后,v.size() = " << v.size() << '\n';// 3: 初始化转换int n = static_cast<int>(3.14); std::cout << "n = " << n << '\n';std::vector<int> v = static_cast<std::vector<int>>(10);std::cout << "v.size() = " << v.size() << '\n';// 4: 弃值表达式static_cast<void>(v2.size());// 5. 隐式转换的逆转换void* nv = &n;int* ni = static_cast<int*>(nv);std::cout << "*ni = " << *ni << '\n';// 6. 数组到指针后随向上转型D a[10];B* dp = static_cast<B*>(a);// 7. 有作用域枚举到 int 或 floatE e = E::ONE;int one = static_cast<int>(e);std::cout << one << '\n';// 8. int 到枚举,枚举到另一枚举E e2 = static_cast<E>(one);EU eu = static_cast<EU>(e2);// 9. 指向成员指针向上转型int D::*pm = &D::m;std::cout << br.*static_cast<int B::*>(pm) << '\n';// 10. void* 到任何类型void* voidp = &e;std::vector<int>* p = static_cast<std::vector<int>*>(voidp);
}

输出 

Hello world,这里是 B!
Hello world,这里是 D!
移动后,v.size() = 0
n = 3
v.size() = 10
*ni = 3
1
0

const_cast

类型转换运算符,可以将 const 和 volatile 限定符从指针或引用类型中去除。它可以用于将常量对象变成非常量对象,从而允许对其进行修改,函数指针和成员函数指针无法用于 const_cast

 示例

#include <iostream>struct type
{int i;type(): i(3) {}void f(int v) const {// this->i = v;                 // 编译错误:this 是指向 const 的指针const_cast<type*>(this)->i = v; // 只要该对象不是 const 就 OK}
};int main() 
{int i = 3;                 // 不声明 i 为 constconst int& rci = i; const_cast<int&>(rci) = 4; // OK:修改 istd::cout << "i = " << i << '\n';type t; // 如果这是 const type t,那么 t.f(4) 会是未定义行为t.f(4);std::cout << "type::i = " << t.i << '\n';const int j = 3; // 声明 j 为 const[[maybe_unused]]    //可能是有意不使用,编译器不会发出警告int* pj = const_cast<int*>(&j);// *pj = 4;      // 未定义行为[[maybe_unused]]void (type::* pmf)(int) const = &type::f; // 指向成员函数的指针// const_cast<void(type::*)(int)>(pmf);   // 编译错误:const_cast 不能用于成员函数指针
}

dynamic_cast

沿继承层级向上、向下及侧向,安全地转换到其他类的指针和引用,失败会返回空指针

#include <iostream>struct V
{virtual void f() {} // 必须为多态以使用运行时检查的 dynamic_cast
};struct A : virtual V {};struct B : virtual V
{B(V* v, A* a){// 构造中转型(见后述 D 的构造函数中的调用)dynamic_cast<B*>(v); // 良好定义:v 有类型 V*,V 是 B 的基类,产生 B*dynamic_cast<B*>(a); // 未定义行为:a 有类型 A*,A 不是 B 的基类}
};struct D : A, B
{D() : B(static_cast<A*>(this), this) {}
};struct Base
{virtual ~Base() {}
};struct Derived: Base
{virtual void name() {}
};int main()
{D d; // 最终派生对象A& a = d; // 向上转型,可以用 dynamic_cast,但不是必须的[[maybe_unused]]D& new_d = dynamic_cast<D&>(a); // 向下转型[[maybe_unused]]B& new_b = dynamic_cast<B&>(a); // 侧向转型Base* b1 = new Base;if (Derived* d = dynamic_cast<Derived*>(b1); d != nullptr){std::cout << "成功从 b1 向下转型到 d\n";d->name(); // 可以安全调用}Base* b2 = new Derived;if (Derived* d = dynamic_cast<Derived*>(b2); d != nullptr){std::cout << "成功从 b2 向下转型到 d\n";d->name(); // 可以安全调用}delete b1;delete b2;
}

reinterpret_cast

重新解释底层位模式在类型间任意转换,实际上转换比static_cast更不安全,

static_cast就是利用C++类型之间的继承关系图和聚合关系图(编译器必须知道),根据一个子对象地址计算另一个子对象的地址。 

reinterpret_cast不关心继承关系,直接把数据类型A的地址解释成另一个数据类型B的地址

 示例

#include <cstdint>
#include <cassert>
#include <iostream>int f() { return 42; }int main()
{int i = 7;// 指针到整数并转回std::uintptr_t v1 = reinterpret_cast<std::uintptr_t>(&i); // 不能误用 static_caststd::cout << "&i 的值是 " << std::showbase << std::hex << v1 << '\n';int* p1 = reinterpret_cast<int*>(v1);assert(p1 == &i);// 到另一函数指针并转回void(*fp1)() = reinterpret_cast<void(*)()>(f);// fp1(); 未定义行为int(*fp2)() = reinterpret_cast<int(*)()>(fp1);std::cout << std::dec << fp2() << '\n'; // 安全// 通过指针的类型别名化char* p2 = reinterpret_cast<char*>(&i);std::cout << (p2[0] == '\x7' ? "本系统是小端的\n": "本系统是大端的\n");// 通过引用的类型别名化reinterpret_cast<unsigned int&>(i) = 42;std::cout << i << '\n';[[maybe_unused]] const int &const_iref = i;// int &iref = reinterpret_cast<int&>(const_iref); // 编译错误——不能去除 const// 必须用 const_cast 代替:int &iref = const_cast<int&>(const_iref);
}

相关文章:

C++基础 强制转换

目录 static_cast&#xff1a;static_cast(expression) const_cast dynamic_cast reinterpret_cast C 提供以下几类转换 static_cast&#xff1a;static_cast<type-id>(expression) tatic_cast 主要用于以下几种情况&#xff1a; 用于显式地将一个表达式转换为另一…...

【python、opencv】opencv仿射变换原理及代码实现

opencv仿射变换原理 仿射变换是opencv的基本知识点&#xff0c;主要目的是将原始图片经过仿射变换矩阵&#xff0c;平移、缩放、旋转成目标图像。用数学公式表示就是坐标转换。 其中x&#xff0c;y是原始图像坐标&#xff0c;u&#xff0c;v是变换后的图像坐标。将公式转换为…...

mac本地部署stable-diffusion

下载Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" ①输入“1”选择中科大版本&#xff0c;然后输入Y(YES)&#xff0c;直接输入开机密码&#xff08;不显示&#xff09;然后回车确认&#xff0c;开始下载 ②…...

dockers安装rabbitmq

RabbitMQ: easy to use, flexible messaging and streaming — RabbitMQhttps://www.rabbitmq.com/ Downloading and Installing RabbitMQ — RabbitMQ docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.12-management 之后参照&#xff1a;dock…...

07、pytest指定要运行哪些用例

官方用例 # 目录结构 | |----test_mod.py | |----testing||----test_dir.py# content of test_mod.py import pytestdef func(x):return x 1def test_mod():print("test_mod function was invoked")assert func(3) 5def test_func():print("test_func was in…...

springboot集成cxf

<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://ma…...

快速认识什么是:Kubernetes

每次谈到容器的时候&#xff0c;除了Docker之外&#xff0c;都会说起 Kubernetes&#xff0c;那么什么是 Kubernetes呢&#xff1f;今天就来一起学快速入门一下 Kubernetes 吧&#xff01;希望本文对您有所帮助。 Kubernetes&#xff0c;一种用于管理和自动化云中容器化工作负…...

YOLOv6 学习笔记

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、YOLOv6贡献和改进二、YOLOv6核心概念三、YOLOv6架构改进四、YOLOv6重参思想五、YOLOv6的损失函数总结 前言 在计算机视觉领域&#xff0c;目标检测技术一直…...

paypal贝宝怎么绑卡支付

一、PayPal是什么 PayPal是一个很多国家地区通用的支付渠道&#xff0c;我们可以把它理解为一项在线服务&#xff0c;相当于美国版的支付宝。你可以通过PayPal进行汇款和收款&#xff0c;相比传统的电汇和西联那类的汇款方式&#xff0c;PayPal更加简单和容易&#xff0c;被很…...

活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新

2023年11月28日&#xff0c;德州仪器(TI)嵌入式技术创新发展研讨会在上海顺利举办。作为TI中国第三方IDH&#xff0c;深圳市信驰达科技有限公司受邀参加&#xff0c;并设置展位&#xff0c;展出CC2340系列低功耗蓝牙模块及TPMS、蓝牙数字钥匙解决方案&#xff0c;与众多业内伙伴…...

Vue 循环走马灯

1、使用 transform: translateX()&#xff0c;循环将滚动内容在容器内偏移&#xff0c;超出容器部分隐藏&#xff1b; 2、避免滚动到末尾时出现空白&#xff0c;需要预留多几个。 3、一次循环偏移的距离scrollLoopWidth 可能受样式影响需要做些微调&#xff0c;比如单个item的…...

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux文件管理(3)》(27)

《Linux操作系统原理分析之Linux文件管理&#xff08;3&#xff09;》&#xff08;27&#xff09; 8 Linux文件管理8.6 文件管理和操作8.6.1 系统对文件的管理8.6.2 进程对文件的管理 8 Linux文件管理 8.6 文件管理和操作 8.6.1 系统对文件的管理 Linux 系统把所有打开的活动…...

【华为数据之道学习笔记】3-2 基础数据治理

基础数据用于对其他数据进行分类&#xff0c;在业界也称作参考数据。基础数据通常是静态的&#xff08;如国家、币种&#xff09;&#xff0c;一般在业务事件发生之前就已经预先定义。它的可选值数量有限&#xff0c;可以用作业务或IT的开关和判断条件。当基础数据的取值发生变…...

GO设计模式——7、适配器模式(结构型)

目录 适配器模式&#xff08;Adapter Pattern&#xff09; 优缺点 使用场景 注意事项 代码实现 适配器模式&#xff08;Adapter Pattern&#xff09; 适配器模式&#xff08;Adapter Pattern&#xff09;是作为两个不兼容的接口之间的桥梁。将一个类的接口转化为客户希望的…...

Java实现TCP一对一通信,实现UDP群聊通信

TCP一对一通信: 实现服务端对话框&#xff1a; 其中可自由更改对话框的样式 import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class QqMain extends JFrame implements ActionListener{public static void …...

Vue + Element 实现按钮指定间隔时间点击

1、业务需求 需要加一个按钮&#xff0c;调用第三方API&#xff0c;按钮十分钟之内只能点击一次&#xff0c;刷新页面也只能点击一次 2、思路 加一个本地缓存的时间戳&#xff0c;通过时间戳计算指定时间内不能点击按钮 3、实现 1&#xff09;vue页面 <template>&l…...

UE Websocket笔记

参考链接 [UE4 C入门到进阶]12.Websocket网络通信 - 哔哩哔哩 包含怎么用Nodejs 写测试服务器 UE4_使用WebSocket和Json&#xff08;上&#xff09; - 知乎 包含Python写测试服务器 UE4_使用WebSocket和Json&#xff08;下&#xff09; - 知乎 示例代码 xxx.Build.cs"W…...

STM32h7 接收各种can id情况下滤波器的配置

1、接收所有数据 /* 此处id2都为0&#xff0c;不进行id校验&#xff0c;接收所有数据*/ static void CAN_Filter_Config(void){FDCAN_FilterTypeDef sFilterConfig1;/* Configure Rx filter */sFilterConfig1.IdType FDCAN_STANDARD_ID;sFilterConfig1.FilterIndex 0;sFilte…...

《深入理解计算机系统》学习笔记 - 第三课 - 浮点数

Floating Point 浮点数 文章目录 Floating Point 浮点数分数二进制示例能代表的数浮点数的表示方式浮点数编码规格化值规格化值编码示例 非规格化的值特殊值 示例IEEE 编码的一些特殊属性四舍五入&#xff0c;相加&#xff0c;相乘四舍五入四舍五入的模式二进制数的四舍五入 浮…...

总结:服务器批量处理http请求的大致流程

总结&#xff1a;服务器批量处理http请求的大致流程 一客户端发起请求&#xff1a;可以多个请求同时发送二Web服务器解析请求&#xff08;如&#xff1a;Nginx&#xff09;&#xff1a;可以多个请求同时解析三Servlet容器接收请求&#xff08;如&#xff1a;tomcat&#xff09;…...

高考解析几何“秒杀”技巧:用极点极线快速搞定椭圆定点定值难题

高考解析几何“秒杀”技巧&#xff1a;用极点极线快速搞定椭圆定点定值难题 解析几何作为高考数学的压轴题型&#xff0c;常常让考生望而生畏。面对复杂的计算和抽象的条件&#xff0c;如何在有限时间内快速找到突破口&#xff1f;极点极线理论作为高等几何中的重要工具&#x…...

用PyTorch和ECANet18搞定RAF-DB表情分类:从数据集下载到模型部署的保姆级教程

基于ECANet18的RAF-DB表情识别实战&#xff1a;从零构建高精度分类模型 人脸表情识别&#xff08;FER&#xff09;作为计算机视觉领域的重要分支&#xff0c;在情感计算、智能交互等领域展现出巨大潜力。本文将带您完整实现一个基于PyTorch和ECANet18的端到端表情识别系统&…...

一种用于并网光伏系统的创新型多层逆变器,以降低总谐波失真(THD)研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 &#x1f381…...

QKeyMapper深度解析:现代输入设备管理系统的架构揭秘与实战指南

QKeyMapper深度解析&#xff1a;现代输入设备管理系统的架构揭秘与实战指南 【免费下载链接】QKeyMapper [按键映射工具] QKeyMapper&#xff0c;Qt开发Win10&Win11可用&#xff0c;不修改注册表、不需重新启动系统&#xff0c;可立即生效和停止。支持游戏手柄映射到键鼠&a…...

UEFITool解析指南:三步骤掌握固件逆向分析的核心技术

UEFITool解析指南&#xff1a;三步骤掌握固件逆向分析的核心技术 【免费下载链接】UEFITool UEFI firmware image viewer and editor 项目地址: https://gitcode.com/gh_mirrors/ue/UEFITool UEFITool是一款功能强大的UEFI固件分析工具&#xff0c;能够帮助你深入探索计…...

时空镜像立体成像楼宇全态透明智慧管控技术解析方案

时空镜像立体成像楼宇全态透明智慧管控技术解析方案一、方案概述当前传统楼宇管控普遍存在二维监控信息碎片化、空间感知能力薄弱、人员定位依赖外设、跨镜头轨迹断裂、身份核验存在漏洞、设备运维滞后、区域管控存在盲区等行业共性痛点&#xff0c;多数系统仅实现视频录像与基…...

AI原生产品管理:多智能体协作如何重塑产品开发工作流

1. 项目概述&#xff1a;当AI成为你的产品经理最近在GitHub上看到一个挺有意思的项目&#xff0c;叫NathanJCW/ai-native-pm-cortex。光看名字&#xff0c;你大概能猜到它想做什么——“AI原生的产品经理大脑”。这可不是一个简单的聊天机器人插件&#xff0c;它试图构建一个完…...

基于IMAP的邮件自动化处理工具mymailclaw配置与实战指南

1. 项目概述&#xff1a;一个轻量级的邮件抓取与处理工具最近在折腾一个需要自动化处理邮件通知的小项目&#xff0c;发现市面上的方案要么太重&#xff0c;要么不够灵活。直到我遇到了psandis/mymailclaw这个项目&#xff0c;它就像一把小巧而锋利的瑞士军刀&#xff0c;专门用…...

Cursor-Tap插件:一键AI代码重构与文档生成实战指南

1. 项目概述&#xff1a;一个为 Cursor 编辑器注入灵魂的插件如果你和我一样&#xff0c;日常重度依赖 Cursor 这款 AI 驱动的代码编辑器&#xff0c;那你一定体会过那种“就差一点”的微妙感受。Cursor 的 AI 能力确实强大&#xff0c;但它的交互方式有时会让人感觉像是在和一…...

基于RAG与向量数据库的智能信息管理系统(IIMS)架构与实现

1. 项目概述&#xff1a;当AI成为你的“第二大脑”最近在折腾一个挺有意思的项目&#xff0c;叫“IIMS-By-AI”。乍一看这个标题&#xff0c;可能有点摸不着头脑&#xff0c;但拆解一下就能明白它的野心&#xff1a;IntelligentInformationManagementSystem&#xff0c; By AI。…...