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…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...
