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

C++Cherno 学习笔记day17 [66]-[70] 类型双关、联合体、虚析构函数、类型转换、条件与操作断点

b站Cherno的课[66]-[70]

  • 一、C++的类型双关
  • 二、C++的union(联合体、共用体)
  • 三、C++的虚析构函数
  • 四、C++的类型转换
  • 五、条件与操作断点——VisualStudio小技巧

一、C++的类型双关

作用:在C++中绕过类型系统
在这里插入图片描述

C++是强类型语言
有一个类型系统,不是所有东西都用auto去声明
可以用auto,毕竟它也是一个关键字

但在JavaScript中,没有变量类型的概念
在创建变量时,不需要声明变量类型
当我们接受它作为函数的参数时,没有真正的类型系统

但C++有一个类型系统
当我们创建变量的时候,必须声明整数或双精度数或布尔数或结构体或者类等等
然而,这种类型系统并不像在其他语言中那样强制,比如java
它们的类型很难绕开,包括C#也是
你虽然也可以绕开类型系统,但要做更多的工作

在C++中,虽然类型是由编译器强制执行的,但您可以直接访问内存
这意味着在代码中一直使用这种类型,比如整数,但实际上,我现在要把这段内存,同样的内存,当作double类型,或者是class类型等
可以很容易地绕过类型系统
你是否要用,取决于你的实际情况
在某些情况下,您绝对不应该规避类型系统,因为类型系统存在是有原因的

#include <iostream>int main()
{int a = 50;//double value = a; 隐式转换double value = (double)a; // 显式转换std::cout << value << std::endl;std::cin.get();
}

在这里插入图片描述

#include <iostream>int main()
{int a = 50;//double value = a; 隐式转换//double value = (double)a; 显式转换double& value = *(double*)&a;value = 0.0;std::cout << value << std::endl;std::cin.get();
}

在这里插入图片描述

#include <iostream>struct Entity {int x, y;
};int main()
{Entity e = { 5, 8 };// 回到了原始的内存操作int* position = (int*)&e;int y = *(int*)((char*)&e + 4);std::cout << y << std::endl;std::cin.get();
}

在这里插入图片描述
我们可以用不同的方式解析同一段内存,从而得到不同的结果,类型只是我们约定的解析内存的方式

类型双关:我要把我拥有的这段内存,当作不同类型的内存来对待
我们需要做的只是将该类型作为指针,然后将其转换为另一个指针
然后如果有必要,还可以对它进行解引用

二、C++的union(联合体、共用体)

在这里插入图片描述

联合体有点像类类型,或者结构体类型
只不过它一次只能占用一个成员的内存
这意思是说,通常如果我们有一个结构体,我们声明比如4个浮点数,
我们可以有4乘以4个字节在这个结构体中,总共是16个字节
因为我们有四个成员,而且很明显
当你不断向类或结构体中添加更多成员时,其大小会不断增长

一个联合体只能有一个成员
如果要声明四个浮点数 ABCD 联合体的大小仍然是4个字节,当改变ABCD的值的时候,内存是一样的
改变a设成5 b的值也是5

你可以像使用结构体或类一样使用它们
你也可以给它添加静态函数或者普通函数、方法等等

通常union是匿名使用的,但是匿名union不能含有成员函数

通常被用来做类型双关,union可读性更强

#include <iostream>struct Vector2 {float x, y;
};struct Vector4 {float x, y, z, w;
};void PrintVector2(const Vector2& vector)
{std::cout << vector.x << "," << vector.y << std::endl;
}int main()
{struct Union{union{float a;int b;};};Union u;u.a = 2.0f;std::cout << u.a << "," << u.b << std::endl;
}

在这里插入图片描述

#include <iostream>struct Vector2 {float x, y;
};struct Vector4 {union{// 匿名的,只是一种数据结构,并没有添加任何东西struct{float x, y, z, w;};struct{Vector2 a, b;};};
};void PrintVector2(const Vector2& vector)
{std::cout << vector.x << "," << vector.y << std::endl;
}int main()
{Vector4 vector = { 1.0f,2.0f,3.0f,4.0f };//vector.x = 2.0f;PrintVector2(vector.a);PrintVector2(vector.b);vector.z = 500.0f;std::cout << "--------------------------" << std::endl;PrintVector2(vector.a);PrintVector2(vector.b);std::cin.get();
}

在这里插入图片描述
union里的成员会共享内存,分配的大小是按最大成员的sizeof, 视频里有两个成员,也就是那两个结构体,改变其中一个另外一个里面对应的也会改变. 如果是这两个成员是结构体struct{ int a,b} 和 int k , 如果k=2 ; 对应 a也=2 ,b不变; union我觉得在这种情况下很好用,就是用不同的结构表示同样的数据 ,那么你可以按照获取和修改他们的方式来定义你的 union结构 很方便

一个联合体的应用场景:开发弱类型语言。例如js,let a=2; 紧接着写a=“abc”;变量a在一个时间点只会是一种类型,那就可以定义一个联合体来表示变量的值。

三、C++的虚析构函数

复习:析构函数~(销毁对象) 虚函数virtual

析构函数:在销毁对象时运行,卸载变量,清理使用过的内存,同时适用于栈和堆分配的对象
虚函数:允许我们在子类中重写方法

虚析构函数:二者结合,对于处理多态问题非常重要

#include <iostream>class Base
{
public:Base() { std::cout << "Base Constructor\n"; }~Base() { std::cout << "Base Destrcctor\n"; }
};class Derived : public Base
{
public:Derived() { std::cout << "Derived Constructor\n"; }~Derived() { std::cout << "Derived Destrcctor\n"; }
};int main()
{Base* base = new Base();delete base;std::cout << "----------------\n" << std::endl;Derived* derived = new Derived();delete derived;std::cin.get();
}

在这里插入图片描述

int main()
{Base* base = new Base();delete base;std::cout << "----------------\n" << std::endl;Derived* derived = new Derived();delete derived;std::cout << "----------------\n" << std::endl;Base* poly = new Derived();delete poly;std::cin.get();
}
// 只有基类的析构函数被调用,派生类的的析构函数没有被调用
// 这样会导致内存泄露

在这里插入图片描述
虚析构函数不是覆写析构函数,而是加上一个析构函数
如果我把基类析构函数改为虚函数
它实际上会调用两个(析构函数)
它会先调用派生类析构函数,然后在层次结构中向上,调用基类析构函数
标记为virtual,意味着c++就会知道在层次结构下的这个方法可能被重写了

一定要确保声明析构函数是虚函数,如果你允许它有子类的话

!!!如果用基类指针来引用派生类对象,那么基类的析构函数必须是 virtual 的,否则 C++ 只会调用基类的析构函数,不会调用派生类的析构函数。

四、C++的类型转换

C++是强类型语言,意味着存在一个类型系统,并且类型是强制的

#include <iostream>class Base
{
public:Base() {}~Base() {}
};class Derived : public Base
{
public:Derived() {}~Derived() {}
};class AnotherClass : public Base
{
public:AnotherClass() {}~AnotherClass() {}
};int main()
{	// 隐式转换//int a = 5;//double value = a;double value = 5.25;//int a = value;//int a = (int)value;double a = value + 5.3;std::cout << a << std::endl;std::cin.get();
}

在这里插入图片描述

#include <iostream>class Base
{
public:Base() {  }~Base() {  }
};class Derived : public Base
{
public:Derived() {  }~Derived() {  }
};class AnotherClass : public Base
{
public:AnotherClass() {}~AnotherClass() {}
};int main()
{	// 隐式转换//int a = 5;//double value = a;double value = 5.25;//int a = value;//int a = (int)value;// C语言风格类型转换double a = (int)value + 5.3;std::cout << a << std::endl;std::cin.get();
}

在这里插入图片描述

#include <iostream>class Base
{
public:Base() {  }virtual ~Base() {  }
};class Derived : public Base
{
public:Derived() {  }~Derived() {  }
};class AnotherClass : public Base
{
public:AnotherClass() {}~AnotherClass() {}
};int main()
{	Derived* derived = new Derived();Base* base = derived;Derived* ac = dynamic_cast<Derived*>(base);std::cin.get();
}

C++风格 共四种主要的cast 类型转换操作符
一个是 static_cast,还有reinterpret_cast、dynamic_cast、const_cat

static_cast:静态类型转换
reinterpret_cast:把这段内存重新解释成别的东西
const_cat:移除或添加变量的const限定
dynamic_cast:很好的方法来查看是否转换成功,与运行时类型信息RTTI(runtime type information)紧密相关
regex正则表达式

五、条件与操作断点——VisualStudio小技巧

关于条件与操作(conditions and actions)应用在断点上
操作断点是允许我们采取某种动作
一般是在碰到断点时打印一些东西到控制台

两种类型的操作断点:
操作断点和条件断点
在这里插入图片描述

相关文章:

C++Cherno 学习笔记day17 [66]-[70] 类型双关、联合体、虚析构函数、类型转换、条件与操作断点

b站Cherno的课[66]-[70] 一、C的类型双关二、C的union&#xff08;联合体、共用体&#xff09;三、C的虚析构函数四、C的类型转换五、条件与操作断点——VisualStudio小技巧 一、C的类型双关 作用&#xff1a;在C中绕过类型系统 C是强类型语言 有一个类型系统&#xff0c;不…...

wordpress 利用 All-in-One WP Migration全站转移

导出导入站点 在插件中查询 All-in-One WP Migration备份并导出全站数据 导入 注意事项&#xff1a; 1.导入部分限制50MB 宝塔解决方案&#xff0c;其他类似&#xff0c;修改php.ini配置文件即可 2. 全站转移需要修改域名 3. 大文件版本&#xff0c;大于1G的可以参考我的…...

springboot+easyexcel实现下载excels模板下拉选择

定义下拉注解 Target(ElementType.FIELD) Retention(RetentionPolicy.RUNTIME) public interface ExcelDropDown {/*** 固定下拉选项*/String[] source() default {};/*** 动态数据源key&#xff08;从上下文中获取&#xff09;*/String sourceMethod() default "";…...

LeetCode.3396.使数组元素互不相同所需的最少操作次数

3396. 使数组元素互不相同所需的最少操作次数 给你一个整数数组 nums&#xff0c;你需要确保数组中的元素 互不相同 。为此&#xff0c;你可以执行以下操作任意次&#xff1a; 从数组的开头移除 3 个元素。如果数组中元素少于 3 个&#xff0c;则移除所有剩余元素。 注意&…...

【工具使用】在OpenBMC中使用GDB工具来定位coredump原因

在OpenBMC调试中&#xff0c;有时会产生coredump却不知道从哪里入手分析&#xff0c;GDB工具就可以提供帮助。 1 编译带GDB工具的镜像 OpenBMC镜像中默认没有加入GDB工具&#xff0c;因此首先需要编译一个带GDB工具的OpenBMC镜像用于调试。在recipes-phosphor/packagegroups/…...

Linux系统(Ubuntu和树莓派)的远程操作练习

文章目录 一、实验一&#xff08;一&#xff09;实验准备&#xff08;二&#xff09;Ubuntu 下的远程操作&#xff08;三&#xff09;树莓派下的远程操作&#xff08;四&#xff09;思考 二、实验二1.talk程序2. C 编写 Linux 进程间通信&#xff08;IPC&#xff09;聊天程序 一…...

雪花算法、md5加密

雪花算法生成ID是一个64位长整型&#xff08;但是也可以通过优化简短位数&#xff09; 组成部分&#xff1a; 时间戳 机器ID 序列号 用途&#xff1a; 分布式系统唯一ID生成&#xff1a;解决数据库自增ID在分布式环境下的唯一性问题、避免UUID的无序性和性能问题 有序性…...

《P2660 zzc 种田》

题目背景 可能以后 zzc 就去种田了。 题目描述 田地是一个巨大的矩形&#xff0c;然而 zzc 每次只能种一个正方形,而每种一个正方形时 zzc 所花的体力值是正方形的周长&#xff0c;种过的田不可以再种&#xff0c;zzc 很懒还要节约体力去泡妹子&#xff0c;想花最少的体力值…...

高效创建工作流,可实现类似unreal engine的蓝图效果,内部使用多线程高效执行节点函数

文章目录 前言&#xff08;Introduction&#xff09;开发环境搭建&#xff08;Development environment setup&#xff09;运行&#xff08;Run test&#xff09;开发者&#xff08;Developer&#xff09;编译&#xff08;Compile&#xff09;报错 前言&#xff08;Introductio…...

Design Compiler:语法检查工具dcprocheck

相关阅读 Design Compilerhttps://blog.csdn.net/weixin_45791458/category_12738116.html?spm1001.2014.3001.5482 dcprocheck是一个在Design Compiler存在于安装目录下的程序&#xff08;其实它是一个指向snps_shell的符号链接&#xff0c;但snps_shell可以根据启动命令名判…...

aws(学习笔记第三十八课) codepipeline-build-deploy-github-manual

文章目录 aws(学习笔记第三十八课) codepipeline-build-deploy-github-manual学习内容&#xff1a;1. 整体架构1.1 代码链接1.2 全体处理架构 2. 代码分析2.1 创建ImageRepo&#xff0c;并设定给FargateTaskDef2.2 创建CodeBuild project2.3 对CodeBuild project赋予权限&#…...

自定义实现C++拓展pytorch功能

ncrelu.cpp #include <torch/extension.h> // 头文件引用部分namespace py pybind11;torch::Tensor ncrelu_forward(torch::Tensor input) {auto pos input.clamp_min(0); // 具体实现部分auto neg input.clamp_max(0);return torch::cat({pos, neg}, …...

深度学习|注意力机制

一、注意力提示 随意&#xff1a;跟随主观意识&#xff0c;也就是指有意识。 注意力机制&#xff1a;考虑“随意线索”&#xff0c;有一个注意力池化层&#xff0c;将会最终选择考虑到“随意线索”的那个值 二、注意力汇聚 这一部分也就是讲第一大点中“注意力汇聚”那个池化…...

京东店铺托管7*16小时全时护航

内容概要 京东店铺托管服务的*716小时全时护航模式&#xff0c;相当于给商家配了个全年无休的"运营管家"。专业团队每天从早7点到晚11点实时盯着运营数据和商品排名&#xff0c;连半夜流量波动都能通过智能系统秒级预警。这种全天候服务可不是单纯拼人力——系统自动…...

遵循IEC62304YY/T0664:确保医疗器械软件生命周期合规性

一、EC 62304与YY/T 0664的核心定位与关系 IEC 62304&#xff08;IEC 62304&#xff09;是国际通用的医疗器械软件生命周期管理标准&#xff0c;适用于所有包含软件的医疗器械&#xff08;如嵌入式软件、独立软件、移动应用等&#xff09;&#xff0c;其核心目标是确保软件的安…...

Android Input——输入系统介绍(一)

Input 是 Android 系统中的一个重要模块&#xff0c;它是负责处理用户输入操作的核心组件。该系统从各种输入设备&#xff08;如触摸屏、键盘、鼠标等&#xff09;获取原始输入事件&#xff0c;并将其转换为 Android 应用可以理解和消费的 KeyEvent 或 MotionEvent 对象。 一、…...

20250408-报错:pre_state = state同更新现象

项目场景&#xff1a; 基于强化学习解决组合优化问题 问题描述 # POMO Rolloutstate, reward, done self.env.pre_step()# next_state statewith autocast():while not done:# 执行动作并获取新状态和奖励selected, prob self.model(state)# 更新状态:因为self.env.step(s…...

如何在服务器里部署辅助域

辅助域&#xff08;Additional Domain Controller&#xff0c;ADC&#xff09;是指在现有的Active Directory&#xff08;活动目录&#xff09;架构中&#xff0c;新增一个或多个域控制器以提高目录服务的可用性和可靠性。以下是辅助域的定义、功能和应用场景的详细说明&#x…...

WPS JS宏编程教程(从基础到进阶)-- 第五部分:JS数组与WPS结合应用

目录 摘要第5章 JS数组与WPS结合应用5-1 JS数组的核心特性核心特性解析5-2 数组的两种创建方式(字面量与扩展操作符)1. 字面量创建2. 扩展操作符创建5-3 数组创建应用:提取字符串中的数字需求说明代码实现5-4 用函数创建数组(new Array、Array.of、Array.from)1. new Arra…...

Kaggle-Housing Prices-(回归预测+Ridge,Lasso,Xgboost模型融合)

Housing Prices 题意&#xff1a; 给出房子的各种特性&#xff0c;让你预测如今房子的价格。 思考&#xff1a; 数据处理&#xff1a; 1.用plt查看散点图&#xff0c;选择对价格影响高的特征值&#xff1a;YearBuilt&#xff0c;YearRemodAdd&#xff0c;GarageYrBlt。但是…...

C语言:32位数据转换为floaf解析

在C语言中&#xff0c;将接收到的32位数据&#xff08;通常是一个unsigned int或int类型&#xff09;转换为float类型可以通过以下方式实现&#xff1a; 除了下面的方法外还有几个方法&#xff0c;参考博客&#xff1a; C语言&#xff1a;把两个16位的数据合成32位浮点型数据 …...

MQTT协议:IoT通信的轻量级选手

文章总结&#xff08;帮你们节约时间&#xff09; MQTT协议是一种轻量级的发布/订阅通信协议。MQTT通信包括连接建立、订阅、发布和断开等过程。MQTT基于TCP/IP&#xff0c;其通信过程涉及多种控制包和数据包。ESP32S3可以通过MQTT协议接收消息来控制IO9引脚上的LED。 想象一…...

GNSS有源天线和无源天线

区别 需要外部供电的就是有源天线&#xff0c;不需要外部供电的是无源天线。 无源天线 一般就是一个陶瓷片、金属片等&#xff0c;结构简单&#xff0c;成本低廉&#xff0c;占用空间及体积小&#xff0c;适合于强调紧凑型空间的导航类产品。 不需要供电&#xff0c;跟设备直…...

欧税通香港分公司办公室正式乔迁至海港城!

3月20日&#xff0c;欧税通香港分公司办公室正式乔迁至香港油尖旺区的核心商业区海港城!左手挽着内地市场&#xff0c;右手牵起国际航道——这波乔迁选址操作堪称“地理课代表”! 乔迁仪式秒变行业大联欢!感谢亚马逊合规团队、亚马逊云、阿里国际站、Wayfair、coupang、美客多…...

Qt 自带的QSqlDatabase 模块中使用的 SQLite 和 SQLite 官方提供的 C 语言版本(sqlite.org)对比

Qt 自带的 QSqlDatabase 模块中使用的 SQLite 和 SQLite 官方提供的 C 语言版本&#xff08;sqlite.org&#xff09;在核心功能上是相同的&#xff0c;但它们在集成方式、API 封装、功能支持以及版本更新上存在一些区别。以下是主要区别&#xff1a; 1. 核心 SQLite 引擎 Qt 的…...

zustand 源码解析

文章目录 实现原理createcreateStore 创建实例CreateStoreImpl 实现发布订阅createImpl 包装返回给用户调用的 hookuseSyncExternalStoreWithSelector 订阅更新zustand 性能优化自定义数据更新createWithEqualityFncreateWithEqualityFnImpl 返回 hookuseSyncExternalStoreWith…...

洛谷题单3-P1423 小玉在游泳-python-流程图重构

题目描述 小玉开心的在游泳&#xff0c;可是她很快难过的发现&#xff0c;自己的力气不够&#xff0c;游泳好累哦。已知小玉第一步能游 2 2 2 米&#xff0c;可是随着越来越累&#xff0c;力气越来越小&#xff0c;她接下来的每一步都只能游出上一步距离的 98 % 98\% 98%。现…...

ETPNav:基于演进拓扑规划的连续环境视觉语言导航模型

1、现有工作的缺陷&#xff1a; 最近&#xff0c;出现了一种基于模块化航路点的方法的新兴趋势&#xff0c;该方法将复杂任务分为航路点生成、子目标规划和导航控制&#xff1a; &#xff08;1&#xff09;在每个决策循环中&#xff0c;代理使用预训练的网络来预测附近的几个…...

Spring Cloud LoadBalancer负载均衡+算法切换

目录 介绍核心功能负载均衡启动两个支付服务订单模块引入依赖LoadBalanced 注解启动订单服务测试结果 负载均衡算法切换总结 介绍 Spring Cloud LoadBalancer 是 Spring Cloud 提供的客户端负载均衡解决方案&#xff0c;提供更现代化的 API 和更好的 Spring 生态系统集成。它支…...

游戏引擎学习第210天

回顾并为今天的工作做准备 今天我们&#xff0c;进行一些编码工作。这部分的编码内容对那些对代码架构感兴趣的人非常有帮助&#xff0c;我认为今天的编码内容会很有教育意义&#xff0c;尤其是在展示一些代码转化的过程中&#xff0c;希望大家能够从中获得一些启发。 接下来…...