C++基础 强制转换
目录
static_cast:static_cast(expression)
const_cast
dynamic_cast
reinterpret_cast
C++ 提供以下几类转换
static_cast:static_cast<type-id>(expression)
tatic_cast 主要用于以下几种情况:
- 用于显式地将一个表达式转换为另一种类型,包括基本类型、指针类型和引用类型。
- 用于将基类指针或引用转换为派生类指针或引用(向下转型)。
- 用于将 void* 指针转换为任意类型的指针。
- 用于将任意类型的指针转换为 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:static_cast(expression) const_cast dynamic_cast reinterpret_cast C 提供以下几类转换 static_cast:static_cast<type-id>(expression) tatic_cast 主要用于以下几种情况: 用于显式地将一个表达式转换为另一…...
【python、opencv】opencv仿射变换原理及代码实现
opencv仿射变换原理 仿射变换是opencv的基本知识点,主要目的是将原始图片经过仿射变换矩阵,平移、缩放、旋转成目标图像。用数学公式表示就是坐标转换。 其中x,y是原始图像坐标,u,v是变换后的图像坐标。将公式转换为…...
mac本地部署stable-diffusion
下载Homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" ①输入“1”选择中科大版本,然后输入Y(YES),直接输入开机密码(不显示)然后回车确认,开始下载 ②…...
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 之后参照: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
每次谈到容器的时候,除了Docker之外,都会说起 Kubernetes,那么什么是 Kubernetes呢?今天就来一起学快速入门一下 Kubernetes 吧!希望本文对您有所帮助。 Kubernetes,一种用于管理和自动化云中容器化工作负…...
YOLOv6 学习笔记
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、YOLOv6贡献和改进二、YOLOv6核心概念三、YOLOv6架构改进四、YOLOv6重参思想五、YOLOv6的损失函数总结 前言 在计算机视觉领域,目标检测技术一直…...
paypal贝宝怎么绑卡支付
一、PayPal是什么 PayPal是一个很多国家地区通用的支付渠道,我们可以把它理解为一项在线服务,相当于美国版的支付宝。你可以通过PayPal进行汇款和收款,相比传统的电汇和西联那类的汇款方式,PayPal更加简单和容易,被很…...
活动回顾|德州仪器嵌入式技术创新发展研讨会(上海站)成功举办,信驰达科技携手TI推动技术创新
2023年11月28日,德州仪器(TI)嵌入式技术创新发展研讨会在上海顺利举办。作为TI中国第三方IDH,深圳市信驰达科技有限公司受邀参加,并设置展位,展出CC2340系列低功耗蓝牙模块及TPMS、蓝牙数字钥匙解决方案,与众多业内伙伴…...
Vue 循环走马灯
1、使用 transform: translateX(),循环将滚动内容在容器内偏移,超出容器部分隐藏; 2、避免滚动到末尾时出现空白,需要预留多几个。 3、一次循环偏移的距离scrollLoopWidth 可能受样式影响需要做些微调,比如单个item的…...
<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux文件管理(3)》(27)
《Linux操作系统原理分析之Linux文件管理(3)》(27) 8 Linux文件管理8.6 文件管理和操作8.6.1 系统对文件的管理8.6.2 进程对文件的管理 8 Linux文件管理 8.6 文件管理和操作 8.6.1 系统对文件的管理 Linux 系统把所有打开的活动…...
【华为数据之道学习笔记】3-2 基础数据治理
基础数据用于对其他数据进行分类,在业界也称作参考数据。基础数据通常是静态的(如国家、币种),一般在业务事件发生之前就已经预先定义。它的可选值数量有限,可以用作业务或IT的开关和判断条件。当基础数据的取值发生变…...
GO设计模式——7、适配器模式(结构型)
目录 适配器模式(Adapter Pattern) 优缺点 使用场景 注意事项 代码实现 适配器模式(Adapter Pattern) 适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。将一个类的接口转化为客户希望的…...
Java实现TCP一对一通信,实现UDP群聊通信
TCP一对一通信: 实现服务端对话框: 其中可自由更改对话框的样式 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、业务需求 需要加一个按钮,调用第三方API,按钮十分钟之内只能点击一次,刷新页面也只能点击一次 2、思路 加一个本地缓存的时间戳,通过时间戳计算指定时间内不能点击按钮 3、实现 1)vue页面 <template>&l…...
UE Websocket笔记
参考链接 [UE4 C入门到进阶]12.Websocket网络通信 - 哔哩哔哩 包含怎么用Nodejs 写测试服务器 UE4_使用WebSocket和Json(上) - 知乎 包含Python写测试服务器 UE4_使用WebSocket和Json(下) - 知乎 示例代码 xxx.Build.cs"W…...
STM32h7 接收各种can id情况下滤波器的配置
1、接收所有数据 /* 此处id2都为0,不进行id校验,接收所有数据*/ 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 编码的一些特殊属性四舍五入,相加,相乘四舍五入四舍五入的模式二进制数的四舍五入 浮…...
总结:服务器批量处理http请求的大致流程
总结:服务器批量处理http请求的大致流程 一客户端发起请求:可以多个请求同时发送二Web服务器解析请求(如:Nginx):可以多个请求同时解析三Servlet容器接收请求(如:tomcat)…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
深入理解JavaScript设计模式之单例模式
目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
