当前位置: 首页 > news >正文

C++中move和forword的区别

首先说结论:

move用于将一个对象的资源所有权从一个对象转移到另一个对象,以避免不必要的复制。它是一种类型转换,表示你希望将一个对象视为一个右值,从而可以被“移动”而不是“复制”。

forward用于完美转发模板参数。它确保在将参数传递给其他函数时,保留参数的值类别(即是左值还是右值)。这对于实现通用函数模板尤其重要。

一、move

1.1、cpp内置对象转移所有权

move 用于转移对象的所有权

std::string s1 = "hello word";
std::string s2 = std::move(s1);
std::cout << s1.size() << ' ' << s1 << std::endl;
std::cout << s2.size() << ' ' << s2 << std::endl;

输出为:

0            
10 hello word

可以看出来对象的所有权已经发生了转移

1.2、自定义对象转移所有权

#include <iostream>
#include <string>
#include <utility>class MyClass {
public:MyClass() : data(new int[10]) {}~MyClass() { delete[] data; }// 移动构造函数MyClass(MyClass&& other) noexcept : data(other.data) {other.data = nullptr;}// 移动赋值运算符MyClass& operator=(MyClass&& other) noexcept {if (this != &other) {delete[] data;data = other.data;other.data = nullptr;}return *this;}private:int* data;
};int main() {MyClass obj1;MyClass obj2 = std::move(obj1); // 调用移动构造函数MyClass obj3;obj3 = std::move(obj2); // 调用移动赋值运算符
}

二、forward

forward用于完美转发,完美转发保留了参数的原始值类别,使得函数可以适应左值和右值传递的情况。

在模板编程中,尤其是当你编写一个接受各种类型参数的泛型函数时,你可能需要将这些参数转发给另一个函数。简单地传递参数可能会导致值类别的丢失,从而引发性能损失或不符合预期的行为。完美转发通过保留参数的原始值类别,确保它们在传递过程中不会被意外地修改。

#include <iostream>
#include <utility> // for std::forward// 一个示例函数,接受一个左值引用和一个右值引用
void process(int& x) {std::cout << "Processing lvalue: " << x << std::endl;
}void process(int&& x) {std::cout << "Processing rvalue: " << x << std::endl;
}// 泛型函数,使用 std::forward 实现完美转发
template <typename T>
void forwardToProcess(T&& arg) {process(std::forward<T>(arg));
}int main() {int x = 10;forwardToProcess(x);           // 传递左值forwardToProcess(20);          // 传递右值return 0;
}

可以看到 forwardToProcess 会根据不同的参数类别选择不同的函数实现。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • spring自定义属性编辑器
  • SOCKS5代理为何比HTTP代理更快?
  • LeetCode63:不同路径II
  • 生成式AI:ChatGPT及其在各行业的应用前景
  • MyBatis-Plus 插件扩展
  • k8s部署jenkins集群时,使用ThinBackup进行定期备份
  • Mybatis Plus分页查询返回total为0问题
  • prometheus通过nginx-vts-exporter监控nginx
  • Android APN type 配置和问题
  • 数据结构之线性表(python)
  • 【数据结构】数据结构系列学习笔记——导航篇
  • 动规part 05
  • 设计模式 组合模式(Composite Pattern)
  • 基于单片机的无线宠物自动喂食系统设计
  • 什么是L2范数
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【347天】每日项目总结系列085(2018.01.18)
  • C++类的相互关联
  • create-react-app项目添加less配置
  • java8-模拟hadoop
  • MySQL用户中的%到底包不包括localhost?
  • nodejs调试方法
  • Phpstorm怎样批量删除空行?
  • Python十分钟制作属于你自己的个性logo
  • Vue UI框架库开发介绍
  • 如何实现 font-size 的响应式
  • 新版博客前端前瞻
  • 原生 js 实现移动端 Touch 滑动反弹
  • 运行时添加log4j2的appender
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • #pragma once与条件编译
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (二)构建dubbo分布式平台-平台功能导图
  • (七)glDrawArry绘制
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (算法)求1到1亿间的质数或素数
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (转)关于多人操作数据的处理策略
  • (转)可以带来幸福的一本书
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .java 9 找不到符号_java找不到符号
  • .net core docker部署教程和细节问题
  • .Net Core 笔试1
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET编程——利用C#调用海康机器人工业相机SDK实现回调取图与软触发取图【含免费源码】
  • .NET学习全景图
  • .NET应用架构设计:原则、模式与实践 目录预览
  • .NET中的Exception处理(C#)
  • ??Nginx实现会话保持_Nginx会话保持与Redis的结合_Nginx实现四层负载均衡
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • [④ADRV902x]: Digital Filter Configuration(发射端)