当前位置: 首页 > 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;…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...