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

C++中的右值引用与移动语义的理解

C++中的右值引用与移动语义的理解

从三个层面出发,什么是右值引用和移动语义;为什么需要右值引用和移动语义、std::move作用

一、什么是右值引用与移动语义

右值引用:C++中定义的对右值的引用

int && a = 5; // 这里a的地址就是这个语句中5的地址
int b = 5; // 这里b的地址和这个语句中5这个临时变量

在这里插入图片描述

**移动语义:**对于含有指针类型作为成员数据的类,使用移动而不是深拷贝进行初始化或者赋值。具体体现就是类的移动构造函数和移动赋值函数;也就是传入一个右值引用(就相当于给这个临时变量),然后让本对象的指针的值直接等于该临时对象指针的值,然后将临时对象的指针再置为空。这样避免了深拷贝那样的内存开销。

二、为什么需要右值引用和移动语义

为了避免像深拷贝操作那样的内存开销。比如现在我有一个类,其定义如下:

class T{char* s; //字符串
public:T(){s=nullptr;}T(const char* s){this->s = new char[strlen(s)+1]; //新分配内存strcpy(this->s, s); //为新分配内存赋值}// 拷贝构造函数T(const T & t){this->s = new char[strlen(t.s)+1]; //新分配内存strcpy(this->s, t.s); //为新分配内存赋值}// 移动构造函数T(T && t){this->s = t.s;t.s = nullptr;}
};

对于T t(T("ikun2")); 语句,没有移动构造函数的话,会调用深拷贝构造函数T(const T & t),会新分配内存。但是如果有移动构造函数的话,该语句会调用移动构造函数,就不会进行新分配内存的操作。

三、std::move

std::move用于将一个对象转为右值引用。相当于告诉编译器这个对象我后续不会再使用,你可以把这个对象占用的内存给分配掉。

void Tensor<float>::Padding(const std::vector<uint32_t>& pads,float padding_value) {CHECK(!this->data_.empty());CHECK_EQ(pads.size(), 4);// 四周填充的维度uint32_t pad_rows1 = pads.at(0);  // upuint32_t pad_rows2 = pads.at(1);  // bottomuint32_t pad_cols1 = pads.at(2);  // leftuint32_t pad_cols2 = pads.at(3);  // right// 请补充代码arma::fcube new_data(pad_rows1+pad_rows2+this->data_.n_rows, pad_cols1+pad_cols2+this->data_.n_cols, this->data_.n_slices);new_data.fill(padding_value);new_data.subcube(pad_rows1, pad_cols1, 0,pad_rows1+this->data_.n_rows-1, pad_cols1+this->data_.n_cols-1,this->data_.n_slices-1)=this->data_;this->data_ = std::move(new_data);
}

比如这个函数最后使用this->data_ = std::move(new_data);因为new_data后续不会再被用到,且为了this->data不用再重新分配内存来接收new_data的值,所以使用std::move减小内存开销,提高性能;


文章转载自:

http://Gi24aQ4I.pdwzr.cn
http://63a2R8h1.pdwzr.cn
http://CWmND8ih.pdwzr.cn
http://i5iUYUMH.pdwzr.cn
http://I98BWRa8.pdwzr.cn
http://sCmEVwEs.pdwzr.cn
http://zJFk1StR.pdwzr.cn
http://tIqEHD5W.pdwzr.cn
http://d7eYOrGZ.pdwzr.cn
http://5eStdV7v.pdwzr.cn
http://dzCTYLcC.pdwzr.cn
http://0j6kGWqI.pdwzr.cn
http://IfS6gG2u.pdwzr.cn
http://ISt24l9G.pdwzr.cn
http://TTp70n0t.pdwzr.cn
http://aEXswFhg.pdwzr.cn
http://PO3QfUPf.pdwzr.cn
http://VfP7jRrO.pdwzr.cn
http://ddlalSTG.pdwzr.cn
http://tKPR7vf7.pdwzr.cn
http://CrOihCCD.pdwzr.cn
http://pD5o8qgs.pdwzr.cn
http://LCtMk40q.pdwzr.cn
http://UhqzqCOW.pdwzr.cn
http://55g8LIWu.pdwzr.cn
http://qSmQQXhI.pdwzr.cn
http://622qQ8ZM.pdwzr.cn
http://aYN0d96h.pdwzr.cn
http://qe0q0Z4s.pdwzr.cn
http://kjo5sri6.pdwzr.cn
http://www.dtcms.com/a/236170.html

相关文章:

  • @Transactional注解失效的原因有哪些?
  • 如何对Video视频进行SEO优化?
  • OLED(SSD306)移植全解-基于IIC
  • Semaphore - 信号量
  • CPP基础
  • 西门子 S7-1200 PLC 海外远程运维技术方案
  • DAX权威指南8:DAX引擎与存储优化
  • 第七章:未名湖畔的樱花网关
  • 书籍推荐 --- 《筚路维艰:中国经济社会主义路径的五次选择》
  • 【信息系统项目管理师-案例真题】2025上半年(第二批)案例分析答案和详解(回忆版)
  • ​​Java 异常处理​​ 的详细说明及示例,涵盖 try-catch-finally、自定义异常、throws 与 throw 的核心概念和使用场景
  • 在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
  • Benchmarking Potential Based Rewards for Learning Humanoid Locomotion
  • 关于锁策略的简单介绍
  • 固态继电器与驱动隔离器:电力系统的守护者
  • C++.OpenGL (6/64)坐标系统(Coordinate Systems)
  • 为什么要对邮件列表清洗?
  • C++ --- vector
  • 深入理解指针(二)
  • [蓝桥杯]整理玩具
  • 如何使用 Bulk Rename Utility 批量为文件名添加统一后缀?
  • CountDownLatch和CyclicBarrier
  • 森马下沙奥莱旗舰店盛大启幕:以“新常服“理念重塑消费体验新范式
  • 7.2.1_顺序查找
  • 基于最大相邻夹角的边缘点提取(matlab)
  • Qwen2.5-VL - 模型结构
  • caliper config.yaml 文件配置,解释了每个配置项的作用和注意事项
  • AIGC 基础篇 Python基础 01
  • 优化电脑的磁盘和驱动器提高电脑性能和延长硬盘寿命?
  • Steam 搬砖项目深度拆解:从抵触到真香的转型之路