【嵌入式八股4】C++:引用、模板、哈希表与 I/O

news2025/4/19 8:26:12

1. 左值引用与右值引用

左值与右值的定义

  • 左值:指那些可以在表达式后取得地址的对象。换句话说,左值代表一个可以出现在赋值号(=)左边的值,也可以被修改。例如,变量、数组元素、以及通过引用或指针访问的对象都属于左值。

    例如:int a = 10; 其中 a 是左值。

  • 右值:指那些无法在表达式后取得地址的临时对象或字面量。右值代表一个临时值,它只能出现在赋值号的右边,不能直接修改。常见的右值包括数字常量、字符串常量、临时变量、以及通过表达式返回的临时对象。

    例如:int a = 10; 其中 10 是右值。

右值引用与 C++11

C++11引入了右值引用的概念,使用 && 来表示右值引用,允许程序员更方便地操作右值并实现移动语义完美转发

int&& r = 42; // 创建一个右值引用

2. 移动语义与完美转发

移动语义

std::move 是一个函数模板,它将给定的对象转换为右值,通常用于表示移动而非复制对象的所有权。通过 std::move,我们可以避免昂贵的对象复制操作,从而提高程序的性能。

int main() {
    std::vector<int> source = {1, 2, 3, 4, 5};

    // 使用std::move将source的所有权转移到destination
    std::vector<int> destination = std::move(source);

    // source现在为空,已经移动到destination
    std::cout << "Size of source: " << source.size() << std::endl; // 输出 0
    std::cout << "Size of destination: " << destination.size() << std::endl; // 输出 5

    return 0;
}

完美转发

std::forward 是另一个函数模板,主要用于在函数参数转发时保持其原始类型。与 std::move 类似,但 std::forward 可以根据传入的参数类型(左值或右值)自动转发。

在模板函数中,std::forward 使得我们能够精确地转发参数,保持参数的类型和生命周期,从而避免不必要的拷贝操作。

// 接受右值引用的函数
void processValue(int&& x) {
    std::cout << "Processing rvalue: " << x << std::endl;
}

// 使用std::forward转发参数
template<typename T>
void forwardFunction(T&& arg) {
    processValue(std::forward<T>(arg)); // 完美转发
}

int main() {
    int value = 42;

    // 传递左值
    forwardFunction(value);

    // 传递右值
    forwardFunction(std::move(value));

    return 0;
}

std::forward 的优势

  1. 避免多余的拷贝:对于左值,std::forward 保证其以左值引用传递,避免拷贝;而对于右值,std::forward 则会触发移动操作。

  2. 精确匹配重载函数std::forward 可以帮助我们精确地选择左值或右值版本的重载函数。

  3. 消除重载冗余:通过引用折叠规则,std::forward 可以减少代码冗余,避免为左值和右值分别定义不同的重载。

总结来说,std::forward 可以帮助我们高效地转发函数参数,减少不必要的拷贝和创建冗余的重载。

3. 模板类

模板类是C++中的一个强大特性,允许我们创建类型安全且灵活的类。

模板类的定义和使用

// XX.h
template <typename T>
class MyTemplateClass {
private:
    T data;
public:
    MyTemplateClass(T value) : data(value) {}  // 构造函数

    void printData() const {
        std::cout << "Data: " << data << std::endl;  // 模板类方法
    }
};

// XX.cpp
MyTemplateClass<int> obj1(10);  // 实例化为处理int类型的对象
MyTemplateClass<double> obj2(3.14);  // 实例化为处理double类型的对象

obj1.printData();  // 输出: Data: 10
obj2.printData();  // 输出: Data: 3.14

为什么模板类通常放在头文件中

模板类的实例化发生在编译阶段,因此编译器需要访问模板类的完整定义才能为特定类型生成代码。如果将模板定义和实现分开,编译器将无法实例化模板类,因此模板通常需要放在头文件中。这样做可以确保每个使用模板的翻译单元都能够获得模板的完整定义。

4. 哈希表

哈希表(Hash Table)是一种常用的数据结构,提供了常数时间复杂度的查找、插入和删除操作。它通过哈希函数将键值映射到哈希表中的位置。

哈希碰撞

哈希碰撞是指不同的键通过哈希函数计算得到相同的哈希值。为了解决哈希碰撞,通常有以下几种方法:

  1. 链地址法:每个哈希表位置存储一个链表,用于存放所有具有相同哈希值的元素。
  2. 线性探测法:发生碰撞时,顺序查找下一个空槽并插入元素。
  3. 再哈希法:使用不同的哈希函数计算新的哈希值,从而减少冲突。
  4. 公共溢出区法:将发生碰撞的元素存入另一个溢出区域。

哈希操作

  1. 查找:通过计算键的哈希值,直接定位哈希表中的位置。若有碰撞,则进一步比较键值来判断是否匹配。
  2. 插入:计算键的哈希值并找到对应位置。如果该位置已有元素(碰撞),则根据解决冲突的策略进行处理。
  3. 删除:删除某个键值对时,通过哈希值找到对应位置并删除。如果该位置发生了冲突,可能需要对链表或探测序列进行调整。

当两个对象映射到同一个哈希地址时,是否说明这两个对象相同

当两个对象产生哈希冲突时,它们被映射到了相同的哈希地址上,但并不能确定它们的内容是否相同。两个不同的对象完全可以具有相同的哈希值,因为哈希值只是一个对输入对象进行计算得出的结果。

要确定两个对象是否相同,通常需要使用其他方法,如比较它们的内容、引用或标识符等。哈希地址相同并不代表对象相同,只能说它们在哈希函数中产生了冲突。

哈希表如何解决键值冲突

哈希表(散列表)根据(Key value)直接进行访问的数据结构。映射函数叫做散列函数,存放记录的数组叫做散列表。

哈希值是通过哈希函数计算出来的,通过哈希函数计算出来的哈希值相同,就是哈希冲突,不能完全避免

解决方案:

  1. 开放定址法:发现冲突后寻找下一个空闲散列表位置

  2. 再哈希法:利用不同的哈希函数再次计算哈希值(多轮)

  3. 链地址法:每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表连接起来,因而查找、插入和删除主要在同义词链中进行。

  4. 公共溢出区法:冲突放入溢出表

5. 同步 I/O 与 异步 I/O

同步 I/O

同步 I/O 指的是程序在进行输入/输出操作时会阻塞当前线程,直到 I/O 操作完成才会继续执行后续代码。这种方式简单直观,但如果 I/O 操作较慢,会导致资源浪费和线程阻塞。

异步 I/O

异步 I/O 则是程序在进行输入/输出操作时不会阻塞当前线程,而是继续执行后续代码。在 I/O 操作完成后,系统会通过回调机制或事件通知等方式告知程序操作结果。异步 I/O 能充分利用系统资源,提高并发性能,尤其适合 I/O 密集型的应用程序。

比较

  • 同步 I/O:实现简单,容易理解,但在等待 I/O 完成时可能会浪费 CPU 资源。
  • 异步 I/O:能提高并发性和资源利用率,但实现复杂,通常需要使用回调、事件驱动机制等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2336314.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法思想之模拟

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;算法思想之模拟 发布时间&#xff1a;2025.4.14 隶属专栏&#xff1a;算法 目录 算法介绍核心特点常见问题优化方向 例题替换所有的问号题目链接题目描述算法思路代码实现 提莫攻击题目链接题目描述算法思路代码实现…

测试基础笔记第四天(html)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 html介绍1. 介绍2.骨架标签3.常用标签标题标签段落标签超链接标签图片标签换行和空格标签布局标签input标签&#xff08;变形金刚&#xff09;form标签列表标签 htm…

WPF 中的元素继承层次结构 ,以下是对图中内容的详细说明:

顶层基类 DispatcherObject&#xff1a;处于继承体系最顶端&#xff0c;是一个抽象类。它为 WPF 元素提供了与 Dispatcher&#xff08;调度器&#xff09;交互的能力&#xff0c;Dispatcher 负责管理线程间的消息传递&#xff0c;确保 UI 操作在正确的线程&#xff08;通常是 …

十九、UDP编程和IO多路复用

1、UDP编程 服务端&#xff1a; #include<stdio.h> #include <arpa/inet.h> #include<stdlib.h> #include<string.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <pthread.h> #include &l…

DeepSeek使用001:Word中配置DeepSeek AI的V3和R1模型

文章目录 Word中配置DeepSeek大模型1、勾选开发工具2、信任中心设置3、添加DeepSeek-V3模型4、获取API KEY5、添加DeepSeek-R1模型6、新建组7、测试使用 Word中配置DeepSeek大模型 1、勾选开发工具 打开【选项】 选择【自定义功能区】 2、信任中心设置 打开【信任中心】&…

华为OD机试真题——攀登者2(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 华为OD机试真题《攀登者2》&#xff1a; 目录 题目名称&#xff1a;攀登者2…

Windows卸载重装Docker

卸载 删除C:\Program Files\Docker &#xff0c;如果更改了路径的就找到相关位置进行删除 删除 C:\Users\<用户名>\.docker 清理注册表&#xff0c;不然重装会报错 Exising installation is up to date 按下WindowR唤起命令输入界面&#xff0c;输入regedit打开注…

双目视觉中矩阵等参数说明及矫正

以下是标定文件中各个参数的详细解释&#xff1a; 1. 图像尺寸 (imageSize) 参数值: [1280, 1024]含义: 相机的图像分辨率&#xff0c;宽度为1280像素&#xff0c;高度为1024像素。 2. 相机内参矩阵 (leftCameraMatrix / rightCameraMatrix) 结构: yaml data: [fx, 0, cx, 0,…

PyTorch核心函数详解:gather与where的实战指南

PyTorch中的torch.gather和torch.where是处理张量数据的关键工具&#xff0c;前者实现基于索引的灵活数据提取&#xff0c;后者完成条件筛选与动态生成。本文通过典型应用场景和代码演示&#xff0c;深入解析两者的工作原理及使用技巧&#xff0c;帮助开发者提升数据处理的灵活…

Go:接口

接口既约定 Go 语言中接口是抽象类型 &#xff0c;与具体类型不同 &#xff0c;不暴露数据布局、内部结构及基本操作 &#xff0c;仅提供一些方法 &#xff0c;拿到接口类型的值 &#xff0c;只能知道它能做什么 &#xff0c;即提供了哪些方法 。 func Fprintf(w io.Writer, …

ESP32+Arduino入门(三):连接WIFI获取当前时间

ESP32内置了WIFI模块连接WIFI非常简单方便。 代码如下&#xff1a; #include <WiFi.h>const char* ssid "WIFI名称"; const char* password "WIFI密码";void setup() {Serial.begin(115200);WiFi.begin(ssid,password);while(WiFi.status() ! WL…

CSS高度坍塌?如何解决?

一、什么是高度坍塌&#xff1f; 高度坍塌&#xff08;Collapsing Margins&#xff09;是指当父元素没有设置边框&#xff08;border&#xff09;、内边距&#xff08;padding&#xff09;、内容&#xff08;content&#xff09;或清除浮动时&#xff0c;其子元素的 margin 会…

【数据结构】之散列

一、定义与基本术语 &#xff08;一&#xff09;、定义 散列&#xff08;Hash&#xff09;是一种将键&#xff08;key&#xff09;通过散列函数映射到一个固定大小的数组中的技术&#xff0c;因为键值对的映射关系&#xff0c;散列表可以实现快速的插入、删除和查找操作。在这…

空地机器人在复杂动态环境下,如何高效自主导航?

随着空陆两栖机器人(AGR)在应急救援和城市巡检等领域的应用范围不断扩大&#xff0c;其在复杂动态环境中实现自主导航的挑战也日益凸显。对此香港大学王俊铭基于阿木实验室P600无人机平台自主搭建了一整套空地两栖机器人&#xff0c;使用Prometheus开源框架完成算法的仿真验证与…

第二十一讲 XGBoost 回归建模 + SHAP 可解释性分析(利用R语言内置数据集)

下面我将使用 R 语言内置的 mtcars 数据集&#xff0c;模拟一个完整的 XGBoost 回归建模 SHAP 可解释性分析 实战流程。我们将以预测汽车的油耗&#xff08;mpg&#xff09;为目标变量&#xff0c;构建 XGBoost 模型&#xff0c;并用 SHAP 来解释模型输出。 &#x1f697; 示例…

数据分析实战案例:使用 Pandas 和 Matplotlib 进行居民用水

原创 IT小本本 IT小本本 2025年04月15日 18:31 北京 本文将使用 Matplotlib 及 Seaborn 进行数据可视化。探索如何清理数据、计算月度用水量并生成有价值的统计图表&#xff0c;以便更好地理解居民的用水情况。 数据处理与清理 读取 Excel 文件 首先&#xff0c;我们使用 pan…

hash.

Redis 自身就是键值对结构 Redis 自身的键值对结构就是通过 哈希 的方式来组织的 哈希类型中的映射关系通常称为 field-value&#xff0c;用于区分 Redis 整体的键值对&#xff08;key-value&#xff09;&#xff0c; 注意这里的 value 是指 field 对应的值&#xff0c;不是键…

记录鸿蒙应用上架应用未配置图标的前景图和后景图标准要求尺寸1024px*1024px和标准要求尺寸1024px*1024px

审核报错【①应用未配置图标的前景图和后景图,标准要求尺寸1024px*1024px且需下载HUAWEI DevEco Studio 5.0.5.315或以上版本进行图标再处理、②应用在展开状态下存在页面左边距过大的问题, 应用在展开状态下存在页面右边距过大的问题, 当前页面左边距: 504 px, 当前页面右边距…

Google最新《Prompt Engineering》白皮书全解析

近期有幸拿到了Google最新发布的《Prompt Engineering》白皮书&#xff0c;这是一份由Lee Boonstra主笔&#xff0c;Michael Sherman、Yuan Cao、Erick Armbrust、Antonio Gulli等多位专家共同贡献的权威性指南&#xff0c;发布于2025年2月。今天我想和大家分享这份68页的宝贵资…

如何快速部署基于Docker 的 OBDIAG 开发环境

很多开发者对 OceanBase的 SIG社区小组很有兴趣&#xff0c;但如何将OceanBase的各类工具部署在开发环境&#xff0c;对于不少开发者而言都是比较蛮烦的事情。例如&#xff0c;像OBDIAG&#xff0c;其在WINDOWS系统上配置较繁琐&#xff0c;需要单独搭建C开发环境。此外&#x…