std::move小结

embedded/2024/9/24 23:55:19/
  1. 1. 概念

在 C++ 中,std::move是一个极为实用的工具,它主要用于实现高效的资源转移。然而,需要明确的是,std::move并非真正地 “移动” 任何东西。实际上,它只是将一个对象的状态从一个地方转换到另一个地方,通常是将一个对象的资源所有权从一个对象转移到另一个对象,且在此过程中并不进行复制操作。从本质上来说,std::move是将一个左值转换为右值引用,以便能够调用移动构造函数或移动赋值运算符,从而实现更高效的资源管理。

std::move是一个具有一定迷惑性的函数,对于那些不理解左右值概念的人来说,往往会误以为它能够把一个变量里的内容移动到另一个变量,但事实上,std::move移动不了什么内容,其唯一的功能是把左值强制转化为右值,使得右值引用可以指向左值。其实现方式等同于一个类型转换,即static_cast<T&&>(lvalue)

2. 使用方法

2.1 移动构造函数和移动赋值运算符

首先定义一个自定义类MyClass

class MyClass 
{
public:int* data;MyClass() : data(nullptr) {}MyClass(const MyClass& other) {data = new int;*data = *other.data;std::cout << "Copy constructor called." << std::endl;}MyClass(MyClass&& other) noexcept : data(other.data) {other.data = nullptr;std::cout << "Move constructor called." << std::endl;}~MyClass() {delete data;}MyClass& operator=(const MyClass& other) {if (this!= &other) {delete data;data = new int;*data = *other.data;std::cout << "Copy assignment operator called." << std::endl;}return *this;}MyClass& operator=(MyClass&& other) noexcept {if (this!= &other) {delete data;data = other.data;other.data = nullptr;std::cout << "Move assignment operator called." << std::endl;}return *this;}
};

接着在main函数中使用std::move调用移动构造函数和移动赋值运算符:

int main() 
{MyClass obj1;obj1.data = new int(42);MyClass obj2 = obj1; // 调用复制构造函数MyClass obj3 = std::move(obj1); // 调用移动构造函数MyClass obj4;obj4 = obj2; // 调用复制赋值运算符obj4 = std::move(obj3); // 调用移动赋值运算符return 0;
}

2.2 在容器操作中的应用

std::move在标准容器的操作中也很常见。例如,在std::vector的重新分配过程中,可以使用std::move来避免不必要的复制操作:

std::vector<MyClass> vec1;
vec1.push_back(MyClass());std::vector<MyClass> vec2;
vec2.push_back(std::move(vec1.back())); // 将 vec1 的最后一个元素移动到 vec2
  • 函数参数传递

当函数参数是一个对象时,可以使用std::move将参数转换为右值引用,以便在函数内部进行资源转移

void processObject(MyClass&& obj) 
{// 在这里可以对 obj 进行操作,可能会调用移动构造函数或移动赋值运算符
}int main() 
{MyClass obj;processObject(std::move(obj));return 0;
}

3. 注意事项

使用std::move时要注意,一旦一个对象被移动,它通常处于一个有效但未指定的状态,不应该再对其进行依赖于原始状态的操作。同时,也要确保移动操作是安全和合理的,避免出现资源泄漏或未定义行为。


http://www.ppmy.cn/embedded/116342.html

相关文章

数据结构栈——中缀表达式转后缀表达式

我们平常所用的标准四则运算表达式&#xff0c;如9(3-1)*310/2叫做中缀表达式&#xff0c;后缀表达式为9 3 1 - 3 * 10 2 / &#xff0c;而后缀表达式更容易被计算机所理解计算&#xff0c;我们需要利用栈将中缀表达式转成后缀表达式。 规则&#xff1a;从左到右遍历中缀表达式…

Jenkins基于tag的构建

文章目录 Jenkins参数化构建设置设置gitlab tag在工程中维护构建的版本按指定tag的版本启动服务 Jenkins参数化构建设置 选择参数化构建&#xff1a; 在gradle构建之前&#xff0c;增加执行shell的步骤&#xff1a; 把新增的shell框挪到gradle构建之前&#xff0c; 最后保存 …

[Linux] 通透讲解 什么是进程

标题&#xff1a;[Linux] 通透讲解 什么是进程 个人主页&#xff1a;水墨不写bug &#xff08;图片来自网络&#xff09; 目录 一.深入进程基本概念 二.管理好进程 1.管理好进程的方法 2.描述进程-PCB 3.组织进程 正文开始&#xff1a; 本文按照对进程的先描述再组织进行…

不靠学历,不拼年资,怎么才能月入2W?

之前统计局发布了《2023年城镇单位就业人员年平均工资情况》&#xff0c;2023年全国城镇非私营单位和私营单位就业人员年平均工资分别为120698元和68340元。也就是说在去年非私营单位就业人员平均月薪1W&#xff0c;而私营单位就业人员平均月薪只有5.7K左右。 图源&#xff1a;…

Android中的冷启动,热启动和温启动

在App启动方式中分为三种&#xff1a;冷启动&#xff08;cold start&#xff09;、热启动&#xff08;hot start&#xff09;、温启动&#xff08;warm start&#xff09; 冷启动&#xff1a; 系统不存在App进程&#xff08;App首次启动或者App被完全杀死&#xff09;时启动A…

WebGL光照与材质

目录 基本应用扩展应用WebGL光照和材质的实现涉及到复杂的着色器编程,特别是使用顶点着色器(vertex shader)和片段着色器(fragment shader)来模拟光照效果和材质属性。 基本应用 漫反射光照的基本概念 漫反射光照是指光线照射到物体表面后,光线在各个方向上均匀散射。计算…

QT + WebAssembly + Vue环境搭建

Qt6.7.2安装工具 emsdk安装 git clone https://github.com/emscripten-core/emsdk.git cd emsdk emsdk install 3.1.50 emsdk activate 3.1.50 Qt Creator配置emsdk 效果 参考 GitHub - BrockReece/vue-wasm: Vue web assembly loader Emscripten cmake多版本编译-CSDN博客 …

回归预测|基于鲸鱼优化随机森林数据的数据回归预测Matlab程序 多特征输入单输出WOA-RF

回归预测|基于鲸鱼优化随机森林数据的数据回归预测Matlab程序 多特征输入单输出WOA-RF 文章目录 一、基本原理鲸鱼优化算法&#xff08;WOA&#xff09;随机森林&#xff08;RF&#xff09;WOA-RF的结合总结 二、实验结果三、核心代码四、代码获取五、总结 一、基本原理 WOA-R…