C++对象移动
在某些情况下,对象拷贝后就立即被销毁了,这时利用新标准(C++11)提供的对象移动而非拷贝将大幅提升性能.
1.右值引用
为了支持移动操作,c++11新增了一种引用 - 右值引用(rvalue reference)。这种引用必须指向右值,使用&&声明。
右值引用只能引用临时变量或常量值.
右值引用主要是为类的移动语句做准备的。
int main()
{//int& a = 100; //错误int&& ra = 100;//右值引用,引用一个常量int b = 15;//int& b1 = b * 2 + 10;//错误,不能引用临时变量int&& rb = b * 2 + 10;//合法//double &c = sqrt(100);//错误,不能引用临时变量double&& rc = sqrt(100);//合法cout << ra << "," << rb << "," << rc << endl;return 0;
}
2.移动构造函数和移动赋值函数
在C++中,移动构造函数和移动赋值函数是与对象的资源管理相关的两种操作,它们通常用于优化性能,特别是在处理像动态分配数组或复杂数据结构等资源密集型对象时。这两种操作依赖于C++11引入的右值引用和移动语义。
1)移动构造函数
移动构造函数是一个特殊的构造函数,它接受一个右值引用作为参数。当对象被临时创建并立即用作初始化另一个对象时,会调用移动构造函数。与普通构造函数不同,移动构造函数不会创建新对象的副本(不另外创建需要的资源),它会直接使用原始对象的资源(如动态分配的内存),并将其转移到新的对象。
请注意,原始对象在移动构造后通常不再可用。
示例:
class MyClass {
public: MyClass(MyClass&& other) noexcept : data(other.data) { other.data = nullptr; // 将原始对象的资源置为nullptr,确保它不再拥有这些资源 } private: int* data; // 假设MyClass管理动态分配的内存
};
2)移动赋值函数
移动赋值函数是一个特殊的赋值函数,它接受一个右值引用作为参数。实参是一个临时对象时,会调用移动赋值。与拷贝赋值不同,移动赋值不会创建新对象的副本(不另外创建需要的资源),而是直接使用源对象的资源,并将其转移到目标对象。
请注意,源对象在移动赋值后通常不再可用。
示例:
class MyClass {
public: MyClass& operator=(MyClass&& other) noexcept { if (this != &other) { delete[] data; // 释放当前对象的资源 data = other.data; // 窃取其他对象的资源 other.data = nullptr; // 将原始对象的资源置为null } return *this; }
private: int* data; // 假设MyClass管理动态分配的内存
};
注意:
●使用noexcept关键字标记移动构造函数和移动赋值函数是一个好习惯,因为移动操作通常不抛出异常。这有助于编译器进行优化(不需要为可能的异常做额外的准备),例如在某些情况下使用移动而不是拷贝。
●在实现移动构造函数和移动赋值操作符时,必须确保源对象在移动后处于有效但未定义的状态。通常将源对象的资源设置为nullptr或执行其他适当的清理操作。
●如果类定义了移动构造函数或移动赋值操作符,通常也应该定义相应的拷贝构造函数和拷贝赋值操作符,以确保对象可以以期望的方式进行复制。
3.move函数
move:将左值转为右值引用,一般是为了利用(触发)移动语义来提高性能,避免不必要的拷贝.需要引入utility文件
注意:使用move后源对象不能继续使用
#include <iostream>
#include <utility>
#include <string>
using namespace std;
int main()
{string s1 = "quzijie";string s2 = s1;cout << "s1=" << s1 << endl;cout << "s2=" << s2 << endl;string s3 = move(s1);cout << "s1=" << s1 << endl;cout << "s3=" << s3 << endl;return 0;
}
4.一个具体的示例
#include <iostream> }// 移动构造函数 MyString(MyString&& other) noexcept : len(other.len), data(other.data) {// 将源对象的资源转移到新创建的对象 cout << "MyString 移动 构造函数" << endl;other.data = nullptr;other.len = 0;}//拷贝构造函数MyString(const MyString& other) {cout << "MyString 拷贝构造函数" << endl;len = other.len;data = new char[len + 1];strcpy(data, other.data);}// 赋值运算符 MyString& operator=(const MyString& other) {cout << "MyString = " << endl;if (this != &other) {delete[] data;len = other.len;data = new char[len + 1];strcpy(data, other.data);}return *this;}// 移动赋值运算符 MyString& operator=(MyString&& other) noexcept {cout << "MyString 移动 = " << endl;if (this != &other) {delete[] data;data = other.data;len = other.len;other.data = nullptr;other.len = 0;}return *this;}// 析构函数 ~MyString() {delete[] data;}private:int len;//字符长度char* data;//存放数据的指针
};// 辅助函数,用于创建临时MyString对象
MyString CreateTempString() {return MyString("quzijie");
}int main() {// 使用构造函数/移动构造函数创建s1 cout << "s1: ";MyString s1 = CreateTempString();// 使用移动构造函数创建s2cout << "s2: ";MyString s2 = move(s1);// 使用移动赋值函数将临时对象赋值给s3cout << "s3: ";MyString s3;s3 = CreateTempString();//使用移动赋值函数将s1赋值给s4cout << "s4: ";MyString s4;s4 = move(s1);return 0;
}
如果使用move函数则一定调用对应的移动语义,如果不使用move函数,那么是否使用移动语义这个由编译器自行决定.
相关文章:

C++对象移动
在某些情况下,对象拷贝后就立即被销毁了,这时利用新标准(C11)提供的对象移动而非拷贝将大幅提升性能. 1.右值引用 为了支持移动操作,c11新增了一种引用 - 右值引用(rvalue reference)。这种引用必须指向右值,使用&&声明。 右值引用只能引用临时变量或常量值. 右值引用…...

“华为杯”第十三届中国研究生 数学建模竞赛-E题:粮食最低收购价政策问题研究(续)
目录 4.3 问题三:粮食价格的特殊规律性模型 4.3.1 分析和建模 4.3.2 求解和结果...

(一)django目录介绍
1、生成django项目,得到的目录如下 manage.py:命令行工具,内置多种方式与项目进行交互。在命令提示符窗口下,将路径切换到项目并输入python manage.py help,可以查看该工具的指令信息。 默认的数据库工具,sqlite 在…...

leetcode5 最长回文子串
给你一个字符串 s,找到 s 中最长的 回文 子串。 示例 1: 输入:s "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。示例 2: 输入:s "cbbd" 输…...

《论文阅读》通过顺序不敏感的表示正则化实现稳健的个性化对话生成 ACL 2023
《论文阅读》通过顺序不敏感的表示正则化实现稳健的个性化对话生成 ACL 2023 前言 相关个性化生成论文推荐简介问题定义方法损失函数实验结果 前言 亲身阅读感受分享,细节画图解释,再也不用担心看不懂论文啦~ 无抄袭,无复制,纯手…...

python采集汽车价格数据
python采集汽车价格数据 一、项目简介二、完整代码一、项目简介 本次数据采集的目标是车主之家汽车价格数据,采集的流程包括寻找数据接口、发送请求获取响应、解析数据和持久化存储,先来看一下数据情况,完整代码附后: 二、完整代码 #输入请求页面url #返回html文档 imp…...

德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第四周) - 语言建模
语言建模 1. 统计语言模型2. N-gram语言建模 2.1. N-gram语言模型中的平滑处理 3. 语言模型评估4. 神经语言模型5. 循环神经网络 5.1. Vanilla RNN5.2. LSTM 1. 统计语言模型 统计语言模型旨在量化自然语言文本中序列的概率分布,即计算一个词序列(如一…...

Jitsi meet 退出房间后,用户还在房间内
前言 Jitsi Meet 如果客户端非正常退出会议,会产生用户还在房间内,实际用户已经退出的情况,需要一段时间内,才会在UI离开房间,虽然影响不大,但是也容易导致体验不好。 保活 Jitsi Meet 会和前端做一个保…...

Java 18 新特性
Java 作为一门广泛应用于企业级开发和系统编程的编程语言,一直以来都在不断进化和改进。2022 年发布的 Java 18 版本为开发者带来了一些新的特性和改进,这些特性不仅提升了开发效率,还进一步增强了 Java 语言的功能和灵活性。本文将深入探讨 …...

c++基础创建对象
在C中,test a; 和 test a new test(); 是两种不同的初始化或创建对象的方式,而且它们之间存在根本的区别。 test a; 这是对象a的栈上分配。在声明test a;时,编译器会在栈上为a分配内存,并调用test类的默认构造函数(…...

WHAT - 容器化系列(二)- docker
目录 一、前言二、Docker镜像:可运行软件包三、Docker容器:可执行环境四、容器和镜像的关系五、创建镜像的过程5.1 编写Dockerfile5.2 构建Docker镜像5.3 查看构建的镜像5.4 运行Docker容器5.5 验证容器运行状态5.6 推送镜像到镜像仓库(可选&…...

力扣 19题 删除链表的倒数第 N 个结点 记录
题目描述 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入:head [1], n 1 输出:[]示例 3&am…...

渗透测试之Web安全系列教程(二)
今天,我们来讲一下Web安全! 本文章仅提供学习,切勿将其用于不法手段! 目前,在渗透测试领域,主要分为了两个发展方向,分别为Web攻防领域和PWN(二进制安全)攻防领域。Web…...

【算法】在?复习一下快速排序?
基本概念 快速排序是一种基于交换的排序算法,该算法利用了分治的思想。 整个算法分为若干轮次进行。在当前轮次中,对于选定的数组范围[left, right],首先选取一个标志元素pivot,将所有小于pivot的元素移至其左侧,大于…...

matlab安装及破解
一、如何下载 软件下载链接,密码:98ai 本来我想自己生成一个永久百度网盘链接的,但是: 等不住了,所以大家就用上面的链接吧。 二、下载花絮 百度网盘下载速度比上载速度还慢,我给充了个会员,…...

Tree——输出项目的文件结构(Linux)
输出项目中的文件结构可以使用tree命令。tree是一个用于以树状结构显示目录内容的命令行工具。它非常适合快速查看项目的文件结构。安装: sudo apt-get install tree 使用: 在命令行中导航到项目的根目录,输出文件结构。 tree 也可以将结构输…...

UE5 读取本地图片并转换为base64字符串
调试网址:在线图像转Base64 - 码工具 (matools.com) 注意要加(data:image/png;base64,) FString UBasicFuncLib::LoadImageToBase64(const FString& ImagePath) {TArray<uint8> ImageData;// Step 1: 读取图片文件到字节数组if (!…...

【NOIP普及组】税收与补贴问题
【NOIP普及组】税收与补贴问题 💖The Begin💖点点关注,收藏不迷路💖 每样商品的价格越低,其销量就会相应增大。现已知某种商品的成本及其在若干价位上的销量(产品不会低于成本销售),…...

Docker 部署 mysql 服务
linux用法 Container(容器)集合成 Services(服务) 交互集合成 Stack(堆栈)卸载可能存在的旧版本 sudo apt-get update使apt可以通过HTTPS使用存储库(repository) sudo apt-get ins…...

01- Redis 中的 String 数据类型和应用场景
1. 介绍 String 是最基本的 key-value 结构,key 是唯一标识,value 是具体的值,value 其实不仅是字符串,也可以是数字(整数或浮点数),value 最多可以容纳的数据长度是 512M。 2. 内部实现 Str…...

Android音频焦点
什么是音频焦点? 音频焦点是 API 8 中引入的一个概念。它用于传达这样一个事实:用户一次只能专注于一个音频流,例如收听音乐或播客,但不能同时关注两者。在某些情况下,多个音频流可以同时播放,但只有一个是…...

Docker安全配置
Docker安全及日志管理 文章目录 Docker安全及日志管理资源列表基础环境一、Docker安全相关介绍1.1、Docker容器与虚拟机的区别1.1.1、隔离与共享1.1.2、性能与损耗 1.2、Docker存在的安全问题1.2.1、Docker自身漏洞1.2.2、Docker源码问题 1.3、Docker架构缺陷与安全机制1.3.1、…...

文件上传之使用一个属性接收多个文件
在开发过程中,可能遇到这样的业务:文件上传时个数不定,这样我们不能枚举出所有的文件name,这种情况下我们可以使用一个name将所有的文件接收下来; html代码 <!DOCTYPE html> <html lang"en"> …...

chat4-Server端保存聊天消息到mysql
本文档描述了Server端接收到Client的消息并转发给所有客户端或私发给某个客户端 同时将聊天消息保存到mysql 服务端为当前客户端创建一个线程,此线程接收当前客户端的消息并转发给所有客户端或私发给某个客户端同时将聊天消息保存到mysql 本文档主要总结了将聊天…...

vivo鄢楠:基于OceanBase 的降本增效实践
在3 月 20 日的2024 OceanBase 数据库城市行中,vivo的 体系与流程 IT 部 DBA 组总监鄢楠就“vivo 基于 OceanBase 的降本增效实践”进行了主题演讲。本文为该演讲的精彩回顾。 vivo 在1995年于中国东莞成立,作为一家全球领先的移动互联网智能终端公司&am…...

arm cortex-m架构 SVC指令详解以及其在freertos的应用
1. 前置知识 本文基于arm cortex-m架构描述, 关于arm cortex-m的一些基础知识可以参考我另外几篇文章: arm cortex-m 架构简述arm异常处理分析c语言函数调用规范-基于arm 分析 2 SVC指令 2.1 SVC指令位域表示 bit15 - bit12:条件码&#…...

k8s笔记——kubernetes中的三种IP
kubernetes概念 Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控 Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行 Pod:kubernetes的…...

Golang | Leetcode Golang题解之第127题单词接龙
题目: 题解: func ladderLength(beginWord string, endWord string, wordList []string) int {wordId : map[string]int{}graph : [][]int{}addWord : func(word string) int {id, has : wordId[word]if !has {id len(wordId)wordId[word] idgraph a…...

微服务中feign远程调用相关的各种超时问题
1. 引言 在spring cloud微服中,feign远程调用可能是大家每天都接触到东西,但很多同学却没咋搞清楚这里边的各种超时问题,生产环境可能会蹦出各种奇怪的问题。 首先说下结论: 1)只使用feign组件,不使用ribbion组件&…...

springboot整合chatgpt,并且让其可以记录上下文
整合很简单,不过需要几个小条件 1.必须要有openai官方的key 2.国内需要有代理服务器或者国外的服务器把项目部署出去也没问题 我没有使用spring的springAI,听说很方便,日后有机会去体验体验,我今天用了两种方式整合了gpt 1.Ch…...