C++之使用std::move与否的实例区别(二百五十五)

news2024/11/17 11:30:52

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解C++之使用与不使用std::move的区别。

2.std::move介绍

1.std::move作用

std::move 是 C++11 引入的一个函数模板,主要用于转移指针的所有权。

    1. 转移所有权:std::move 将对象的所有权从一个对象转移到另一个对象,通过将参数转换为右值引用,实现对移动语义的支持。
    1. 避免不必要的拷贝:在某些情况下,可以通过使用std::move来避免不必要的拷贝操作,减少资源消耗。
    1. 支持移动语义:通过使用std::move,可以明确表示对于某个对象的移动操作,以提高性能和减少内存占用。
    1. 实现移动构造函数和移动赋值操作符:在自定义类中,可以通过使用std::move来实现移动构造函数和移动赋值操作符,实现高效的对象转移。
    1. 转移临时对象的所有权:在使用临时对象时,可以使用std::move来明确地将临时对象的所有权转移到另一个对象上。
    1. 支持移动语义的标准库类型:许多标准库中的类型(如std::stringstd::vector等)都提供了移动构造函数和移动赋值运算符,可以通过std::move来显式地调用这些函数。
    1. 支持移动语义的模板编程:在模板编程中,使用std::move可以明确表示对于对象的移动语义,使得代码更加清晰和高效。

std::move在 C++ 中扮演着非常重要的角色,为支持移动语义和提高性能提供了强大的工具。通过合理地利用std::move,可以实现对于对象所有权的有效转移,从而提高代码的性能和效率。

3.代码实例

1. 转移对象的所有权:std::move 可以将对象的所有权从一个对象转移到另一个对象,通过将参数转换为右值引用,实现对移动语义的支持。

#include <iostream>
#include <string>

int main() {
    std::string source = "Hello, world!";
    std::string destination = std::move(source);
    std::cout << "source: " << source << std::endl;        // 输出:source: 
    std::cout << "destination: " << destination << std::endl;  // 输出:destination: Hello, world!
    return 0;
}

2. 避免不必要的拷贝:在某些情况下,可以通过使用 std::move 来避免不必要的拷贝操作,减少资源消耗。

#include <string>

void processString(std::string&& s) {
    // 处理字符串
}

int main() {
    std::string str = "Hello";
    processString(std::move(str));  // 避免不必要的拷贝
    return 0;
}

3. 支持移动语义:通过使用 std::move,可以明确表示对于某个对象的移动操作,以提高性能和减少内存占用。

#include <vector>

int main() {
    std::vector<int> source = {1, 2, 3};
    std::vector<int> destination = std::move(source);
    // 现在 source 为空,destination 包含原始数据
    return 0;
}

4. 实现移动构造函数和移动赋值操作符:在自定义类中,可以通过使用 std::move 来实现移动构造函数和移动赋值操作符,实现高效的对象转移。

#include <iostream>

class MyObject {
public:
    // 移动构造函数
    MyObject(MyObject&& other) noexcept {
        // 执行资源移动
    }

    // 移动赋值操作符
    MyObject& operator=(MyObject&& other) noexcept {
        if (this != &other) {
            // 执行资源移动
        }
        return *this;
    }
};

int main() {
    MyObject obj1;
    MyObject obj2 = std::move(obj1);  // 移动构造函数
    MyObject obj3;
    obj3 = std::move(obj2);           // 移动赋值操作符
    return 0;
}

5. 转移临时对象的所有权:在使用临时对象时,可以使用 std::move 来明确地将临时对象的所有权转移到另一个对象上。

#include <vector>

void processVector(std::vector<int>&& vec) {
    // 处理移动过来的临时向量
}

int main() {
    processVector(std::vector<int>{1, 2, 3}); // 将临时向量的所有权转移给 processVector
    return 0;
}

6. 支持移动语义的标准库类型:许多标准库中的类型(如 std::string、std::vector 等)都提供了移动构造函数和移动赋值运算符,可以通过 std::move 来显式地调用这些函数。

#include <vector>

int main() {
    std::vector<int> source = {1, 2, 3};
    std::vector<int> destination = std::move(source); // 调用 std::vector 的移动构造函数
    return 0;
}

7. 支持移动语义的模板编程:在模板编程中,使用 std::move 可以明确表示对于对象的移动语义,使得代码更加清晰和高效。

#include <utility>
#include <vector>

template <typename T>
void processVector(T&& vec){
    std::vector<int> destination = std::move(vec);  // 显式调用 std::move,实现移动语义
    // 对 destination 进行处理
}

int main() {
    std::vector<int> source = {1, 2, 3};
    processVector(std::move(source)); // 在模板函数中使用 std::move 实现移动语义
    return 0;
}

8.使用拷贝对象方式,打印两个vector对比

#include <iostream>
#include <vector>
#include <string>

int main() {
  std::vector<std::string> v1{"hello", "world"};
  std::vector<std::string> v2;

  // 将v1的内容拷贝到v2中,此时两个对象都有值为:"hello world"的字符串
  v2 = v1;

  // v2现在包含了v1的元素
  std::cout << "v2 size: " << v2.size() << std::endl;
  for (const auto& s : v2) { // 遍历v2中的元素
    std::cout << s << " ";
    std::cout << std::endl;
  }
  
  printf("xxx--------------->%s, %s(), line = %d\n",__FILE__,__FUNCTION__,__LINE__);
  for (const auto& s : v1) { // 遍历v1中的元素
    std::cout << s << " ";
    std::cout << std::endl;
  }
  printf("xxx--------------->%s, %s(), line = %d\n",__FILE__,__FUNCTION__,__LINE__);
  return 0;
}

打印:
v1 size: 2
v2 size: 2
hello
world
xxx--------------->move_01.cpp, main(), line = 23
hello
world
xxx--------------->move_01.cpp, main(), line = 28

9.使用std::move转移对象方式,打印两个vector对比

#include <iostream>
#include <vector>
#include <string>

int main() {
  std::vector<std::string> v1{"hello", "world"};
  std::vector<std::string> v2;

  // 将v1的内容移动到v2中,此时v1中的vecrot字符为空
  v2 = std::move(v1);

  // v1现在为空
  std::cout << "v1 size: " << v1.size() << std::endl;

  // v2现在包含了v1的元素
  std::cout << "v2 size: " << v2.size() << std::endl;
  for (const auto& s : v2) { // 遍历v2中的元素
    std::cout << s << " ";
    std::cout << std::endl;
  }
  
  printf("xxx--------------->%s, %s(), line = %d\n",__FILE__,__FUNCTION__,__LINE__);
  for (const auto& s : v1) { // 遍历v1中的元素
    std::cout << s << " ";
    std::cout << std::endl;
  }
  printf("xxx--------------->%s, %s(), line = %d\n",__FILE__,__FUNCTION__,__LINE__);
  return 0;
}

打印:
v1 size: 0
v2 size: 2
hello
world
xxx--------------->move_01.cpp, main(), line = 23
xxx--------------->move_01.cpp, main(), line = 28

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

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

相关文章

Cesium 展示——坐标间的转换

文章目录 需求1. 点击位置会后获取的地球坐标2. 笛卡尔坐标(Cartesian3)3. 地理坐标系分析转换关系如下需求 坐标间的转换 1. 点击位置会后获取的地球坐标 Cesium点击位置会后获取的地球坐标。 2. 笛卡尔坐标(Cartesian3) 笛卡尔坐标系中,表示一个在 x 轴上、y轴上、…

Centos7 单用户模式修改密码 3步搞定 666 (百分比成功)

1.第一步重新服务器 2.进入这个页面按e进入单用户模式 3.找到linux16这行 在后面添加 init/bin/bash 按ctrlx进入 4.注意是事项直接修改是报错passud: Authentication token manipulation error 需要执行权限&#xff1a;mount -o remount,rw /

抽象 I/O设备模型

I/O设备模型框架 RT-Thread提供了一套简单的I/O设备模型框架。 如图所示&#xff0c;它位于硬件和应用程序之间&#xff0c;共分成三层&#xff0c;从上到下分别是I/O设备管理层、设备驱动框架层、设备驱动层。 应用程序通过I/O设备管理接口获得正确的设备驱动&#xff0c;然…

四川竹哲电子商务有限公司怎么样?是真的吗

在当今数字化时代&#xff0c;抖音电商服务逐渐成为了企业营销的重要手段。在这个充满机遇与挑战的领域&#xff0c;四川竹哲电子商务有限公司以其卓越的服务质量&#xff0c;成为了行业内的佼佼者。本文将详细介绍四川竹哲电子商务有限公司的抖音电商服务&#xff0c;帮助您了…

宏基因组分析项目再创新,汞元素循环

汞&#xff08;Hg&#xff09;是一种具有强烈神经毒性的元素&#xff0c;其单质以及多种化合物都有不同程度的毒性&#xff0c;会造成慢性中毒。汞是一种全球性污染物&#xff0c;大气中的汞可通过干湿沉降进入地表水和土壤&#xff0c;环境因素的变化可导致汞的转化。从无机汞…

如何使用iPhone15在办公室观看家里电脑上的4k电影?

如何使用iPhone15在办公室观看家里电脑上的4k电影&#xff1f; 文章目录 如何使用iPhone15在办公室观看家里电脑上的4k电影&#xff1f;1.使用环境要求&#xff1a;2.下载群晖videostation&#xff1a;3.公网访问本地群晖videostation中的电影&#xff1a;4.公网条件下使用电脑…

BUUCTF 荷兰宽带数据泄露 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;解压得到一个.bin文件。 密文&#xff1a; 解题思路&#xff1a; 1、刚开始没什么思路&#xff0c;看了别人的题解&#xff0c;了解到一个新工具RouterPassView。大多数现代路由器都可以让您备…

【JavaEE】Servlet API 详解(HttpServletResponse类方法演示、实现自动刷新、实现自动重定向)

一、HttpServletResponse HttpServletResponse表示一个HTTP响应 Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到 HttpServletResponse 对象中 然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通…

2024CFA一级二级三级双机构网课资源

复习流程 我自己的复习流程是这样的&#xff0c;按照这个踏实去复习的话100&#xff05;可以过&#xff1a; 第一轮学习&#xff08;30-40天左右&#xff09;&#xff1a;把所有reading学习一遍&#xff0c;每天上午看新的reading&#xff0c;下午复习前一天上午学习的reading…

如何准备2024年的系统设计面试?

1 前言 如果你正在准备软件工程师或软件开发人员的面试,那么你可能知道由于其开放性质和广泛性,准备系统设计是多么困难,但同时你也不能忽略它。在软件工程界,如果你正在申请高级工程师/主管/架构师或更高级别的角色,系统设计是最受追捧的技能,也是整个过程中最重要的环节之一…

记一次线上问题引发的对 Mysql 锁机制分析 | 京东物流技术团队

背景 最近双十一开门红期间组内出现了一次因 Mysql 死锁导致的线上问题&#xff0c;当时从监控可以看到数据库活跃连接数飙升&#xff0c;导致应用层数据库连接池被打满&#xff0c;后续所有请求都因获取不到连接而失败 整体业务代码精简逻辑如下&#xff1a; Transaction p…

算法通关村——数组中第K大的数字

数组中第K大的数字 1、题目描述 ​ LeetCode215. 数组中的第K个最大元素。给定整数数组nums和整数k&#xff0c;请返回数组中第k个最大的元素。请注意&#xff0c;你需要找的是数组排序后的第k个最大的元素&#xff0c;而不是第k个不同的元素。 示例1&#xff1a; 输入&#…

五、nacos安装指南

Nacos安装指南 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; GitHub主页&#xff1a;https://github.com/alibaba/nacos GitHub的Release下载…

【Web 实战】记一次攻防实战

经典开局一个登录框 由于漏洞应该还未修复。对于数据和相关网址打个码见谅一下 常规思路&#xff08;爆破&#xff09; 常规操作进行一波 尝试弱口令然后开始爆破 对于此种有验证码的爆破&#xff0c;可以借用一个bp插件。 captcha-killer-modified-jdk14.jar 具体使用我就…

centos8 执行yum install ntpdate命令,报错未找到匹配的参数: ntpdate

1、执行 yum install ntpdate 报错 上次元数据过期检查&#xff1a;1:17:06 前&#xff0c;执行于 2023年11月15日 星期三 10时32分18秒。 未找到匹配的参数: ntpdate 错误&#xff1a;没有任何匹配: ntpdate 报错截图&#xff1a; 2、CentOS8系统中&#xff0c;原有的时间…

GPT 5也要来了?看看​OpenAI CEO Sam Altman最近的采访

OpenAI CEO Sam Altman 在接受金融时报采访中&#xff0c;透露了更多OpenAI的计划&#xff1a;他们正在寻求从微软获得更多资金支持&#xff0c;以构建真正的通用人工智能&#xff08;AGI&#xff09;。同时还透露了关于GPT 5的一些信息和公司AGI愿景目标&#xff01;他认为&am…

使用order by 排序后的是10 6 7 8 9 而不是 6 7 8 9 10?

问题 sql order by 排序后的为什么 是10 6 7 8 9 而不是 6 7 8 9 10? 思路 在 SQL 中&#xff0c;ORDER BY 默认的排序方式是升序&#xff08;从小到大&#xff09;。所以&#xff0c;如果您简单地使用 ORDER BY 对某个列进行排序&#xff0c;它会将数字按照升序排列&#…

物流接单APP源码 货运APP源码 拉货搬家app源码 货运小程序uniapp+thinkphp

拉货搬家大货车货运物流运输货拉拉货跑腿司机接单物流货运 技术栈 : 后端php7.0版本 框架 thinkphp mysq5.6 前端 uniapp 用户列表 用户分组 实名认证 驾驶证认证 车主认证 搬家拉货 优惠营销 微信管理 评论管理

【仿真】ruckig在线轨迹生成器示例

该场景说明了使用 CoppeliaSim 中提供的 Ruckig 在线轨迹生成功能的各种方法&#xff1a; 1. 在线程脚本内使用单个阻塞函数&#xff08;红色&#xff09; 2. 在线程脚本中使用多个非阻塞函数&#xff08;黄色&#xff09; 3. 在非线程脚本中使用多个非阻塞函数&#xff08;…