C++之move函数的使用

在 C++ 中,std::move 是一个标准库函数,用于实现“移动语义”(Move Semantics),这是 C++11 引入的一个重要特性。std::move 允许你将对象的资源“转移”到另一个对象,从而避免不必要的复制操作,提高效率。

什么是 std::move

std::move 是一个类型转换函数,它将其参数转换为右值引用,从而使得可以利用对象的移动构造函数或移动赋值操作符进行资源的转移。

定义

template <typename T>
typename std::remove_reference<T>::type&& move(T&& t) noexcept;

使用 std::move 的场景

1. 移动构造函数和移动赋值操作符
当你希望通过移动语义而非复制来初始化或赋值对象时,可以使用 std::move。移动构造函数和移动赋值操作符会接管对象的资源,而不是复制资源,这样可以提高效率。

示例

#include <iostream>
#include <utility> // 为了使用 std::move

class Simple {
public:
    // 构造函数
    Simple(int value) : value(new int(value)) {
        std::cout << "构造函数: " << *value << "\n";
    }

    // 移动构造函数
    Simple(Simple&& other) noexcept : value(other.value) {
        other.value = nullptr; // 将 other 的资源指针置为空
        std::cout << "移动构造函数\n";
    }

    // 移动赋值操作符
    Simple& operator=(Simple&& other) noexcept {
        if (this != &other) { // 确保不是自我赋值
            delete value; // 释放当前对象的资源
            value = other.value; // 获取 other 的资源
            other.value = nullptr; // 将 other 的资源指针置为空
            std::cout << "移动赋值操作符\n";
        }
        return *this;
    }

    // 析构函数
    ~Simple() {
        if (value) {
            delete value; // 释放资源
            std::cout << "析构函数\n";
        }
    }

private:
    int* value; // 动态分配的内存,用来存储整数
};

int main() {
    Simple a(10);         // 创建对象 a,内部存储 10
    Simple b = std::move(a); // 使用移动构造函数,将 a 的资源转移到 b
    Simple c(20);         // 创建对象 c,内部存储 20
    c = std::move(b);    // 使用移动赋值操作符,将 b 的资源转移到 c
}

输出

  1. 构造函数: 10

    • 创建对象 avalue 初始化为 10。
  2. 移动构造函数

    • 创建对象 b,通过移动构造函数将 a 的 value 资源转移到 b。此时 a 的 value 指针被置为空(nullptr)。
  3. 析构函数

    • 销毁对象 a。由于 a 的 value 已被置为 nullptr,所以没有实际的资源释放操作。
  4. 构造函数: 20

    • 创建对象 cvalue 初始化为 20。
  5. 移动赋值操作符

    • 使用移动赋值操作符将 b 的 value 资源转移到 c 中。b 的 value 被置为空(nullptr)。
  6. 析构函数

    • 销毁对象 b。由于 b 的 value 已被置为 nullptr,所以没有实际的资源释放操作。
  7. 析构函数

    • 销毁对象 c。释放之前由 b 所持有的资源(即 value)。

容器中的移动语义


在 STL 容器中,std::move 常用于避免不必要的复制操作。比如,当将一个大的容器元素插入到另一个容器时,可以使用 std::move 来高效地转移资源。

示例

#include <iostream>
#include <vector>
#include <utility> // For std::move

int main() {
    std::vector<int> vec1 = {1, 2, 3, 4, 5};
    std::vector<int> vec2 = std::move(vec1); // 使用 std::move 进行资源转移
    for (int value : vec2) {
        std::cout << value << " ";
    }
    std::cout << std::endl;

    std::cout << "vec1 size: " << vec1.size() << std::endl; // vec1 现在是空的
}

输出

1 2 3 4 5 
vec1 size: 0

 注意事项

  • 避免使用 std::move 后继续访问被移动的对象:移动后的对象处于“有效但未指定”状态,应避免对其进行任何操作,除了赋值或销毁。
  • std::move 只是一个类型转换函数:它本身不会执行任何资源移动的操作。真正的资源转移发生在调用移动构造函数或移动赋值操作符时。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通过C# 裁剪PDF页面

在处理PDF文档时&#xff0c;有时需要精确地裁剪页面以适应特定需求&#xff0c;比如去除广告、背景信息或者仅仅是为了简化文档内容。 本文将指导如何使用免费.NET控件通过C#实现裁剪PDF页面。 免费库 Free Spire.PDF for .NET 支持在 .NET (C#, VB.NET, ASP.NET, .NET Core)…

java数据结构----图

图的存储结构: 代码实现 public class Graph {// 标记顶点数目private int V;// 标记边数目private int E;// 邻接表private Queue<Integer>[] adj;public Graph(int v) {V v;this.E 0;this.adj new Queue[v];for (int i 0; i < adj.length; i) {adj[i] new Queu…

使用阿里OCR身份证识别

1、开通服务 免费试用 2、获取accesskay AccessKeyId和AccessKeySecret 要同时复制保存下来 因为后面好像看不AccessKeySecret了 3.Api 参考 https://help.aliyun.com/zh/ocr/developer-reference/api-ocr-api-2021-07-07-recognizeidcard?spma2c4g.11186623.0.0.7a9f4b1e5C…

PHP及Java等其他语言转Go时选择GoFly快速快速开发框架指南

概要 经过一年多的发展GoFly快速开发框架已被一千多家科技企业或开发者用于项目开发&#xff0c;他的简单易学得到其他语言转Go首选框架。且企业版的发展为GoFly社区提供资金&#xff0c;这使得GoFly快速框架得到良好的发展&#xff0c;GoFly技术团队加大投入反哺科技企业和开…

红黑树的插入(NGINX源码)

下载并查看NGINX源码 访问NGINX下载页面&#xff0c;找到所需版本 https://nginx.org/en/download.html 使用wget下载源码包&#xff0c;替换版本号为所需版本 wget http://nginx.org/download/nginx-1.24.0.tar.gz解压源码包 tar -xzvf nginx-1.24.0.tar.gz进入解压后的目…

【算法题】64. 最小路径和-力扣(LeetCode)

【算法题】64. 最小路径和-力扣(LeetCode) 1.题目 下方是力扣官方题目的地址 64. 最小路径和 给定一个包含非负整数的 *m* x *n* 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 **说明&#xff1a;**每次只能向下或者…

Tiny Universe - Llama3架构

Llama3和Llama2和Qwen2的整体架构相似&#xff0c;本篇文章主要讲解它们的一些主要不同点。 关于Qwen2架构可参考 Qwen2架构 学习笔记 llama3区别于llama2在模型层面的区别主要体现在全模型使用GQA。 基础知识 MLP MLP&#xff08;Multi-Layer Perceptron&#xff09;多层感…

1 elasticsearch安装

【0】官网参考 https://www.elastic.co/guide/en/elasticsearch/reference/7.11/targz.html 【1】Centos7 下载安装 【1.1】下载 官网&#xff1a;Download Elasticsearch | Elastic 选择好自己想要的相关版本即可&#xff1b; 【2】Centos7.X 前置环境配置&#xff08;uli…

STM32MP157/linux驱动学习记录(二)

38.Linux INPUT 子系统实验 按键、鼠标、键盘、触摸屏等都属于输入(input)设备&#xff0c;Linux 内核为此专门做了一个叫做 input子系统的框架来处理输入事件。输入设备本质上还是字符设备&#xff0c;只是在此基础上套上了 input 框架&#xff0c;用户只需要负责上报输入事件…

vue使用vue-i18n实现国际化

我使用的是vue2.6版本&#xff0c;具体使用其他版本可以进行修改 一、安装 npm install vue-i18n -D 二、配置 1、文件配置 ①在src下创建 i18n 目录 ②在 i18n 目录下创建 langs 文件夹 和 index.js文件&#xff0c;具体如下 2、index.js代码如下&#xff0c;这里使用了…

[Python]一、Python基础编程

F:\BaiduNetdiskDownload\2023人工智能开发学习路线图\1、人工智能开发入门\1、零基础Python编程 1. Python简介 Python优点: 学习成本低开源适应人群广泛应用领域广泛1.1 Python解释器 下载地址:Download Python | Python.org 1.2 Python开发IDE -- Pycharm 2. 基础语法…

链表--(1)链表的概念

前言引入 之前我们学习了数组这一概念,使用数组可以在编程时增加程序的灵活性。但在c语言中不允许定义动态数组的类型也不能随意调整数组的大小,往往会导致内存空间的浪费。由此我们推出链表。链表是动态进行内存分配的一种结构,它可以随时为其结点分配需要的存储空间也方便…

CSS中的位置定位总结

文章目录 静态定位相对定位绝对定位固定定位 静态定位 静态定位(position:static)/默认的文档流布局 块级元素按照书写顺序从上往下依次排列行内/行内块元素按照书写顺序从左到右依次排列&#xff0c;一行放不下才换行文档流中的元素都是紧密排布的&#xff0c;没有大的空隙&…

windows查找端口号被占用

在很多开发的时候&#xff0c;可能端口号有被占用的情况&#xff0c;导致项目打不开。 用下面这个命令即可&#xff1a; 比如我的3000端口被占用&#xff0c;我找找哪个进程在占用我的3000端口号

数据结构:堆的算法

目录 一堆的向上调整算法二堆的向下调整算法三堆的应用:堆排序四TOPK问题 一堆的向上调整算法 我们在堆中插入一个数据一般实在堆的最后插入然后可以一步一步与上层结点&#xff08;父结点进行比较&#xff09;&#xff0c;继而进行交换&#xff0c;完成二叉树的结构&#xff0…

人工智能辅助汽车造型设计

随着科技的不断进步&#xff0c;人工智能&#xff08;AI&#xff09;在各个领域的应用越来越广泛&#xff0c;汽车设计行业也不例外。尤其在车辆外观造型设计中&#xff0c;AI正在成为设计师的重要助手&#xff0c;通过提供强大的工具和独特的创意方式&#xff0c;革新了传统设…

code eintegrity npm err sha512

当 npm install 出现报错的时候&#xff1a; 你应该这样去解决&#xff1a; 删除 package-lock.json 文件&#xff0c;重新执行 npm install。 问题出现的原因 EINTEGRITY 错误码表示在npm缓存中无法找到 指定sha512校验合的模块。 出现这个问题的原因是缓存不一致&…

把设计模式用起来!(4) 用不好模式?之原理不明

&#xff08;清华大学出版社 《把设计模式用起来》书稿试读&#xff09; 上一篇&#xff1a;把设计模式用起来&#xff01;&#xff08;3&#xff09;用不好模式&#xff1f;之时机不对 为什么用不好设计模式&#xff1f;——原理不明 难搞的顾客&#xff1a;“抹这种霜&#…

使用c#制作一个小型桌面程序

封装dll 首先使用visual stdio 创建Dll新项目,然后属性管理器导入自己的工程属性表&#xff08;如果没有可以参考visual stdio 如何配置opencv等其他环境&#xff09; 创建完成后 系统会自动生成一些文件&#xff0c;其中 pch.cpp 先不要修改&#xff0c;pch.h中先导入自己需…