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)…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
