C++11右值引用

news2024/11/14 16:35:14

目录

  • 概念
    • 左值和右值
    • 左值引用和右值引用
  • 使用
    • 左值引用
    • 右值引用和移动语义
  • 完美转发
    • 万能引用
    • 完美转发

概念

左值和右值

  • 左值

左值是一个可以被取地址、修改的对象或变量,其具有固定的内存地址。

左值可以出现在赋值语句的左边,因为它们表示一个可被修改的存储位置。

int a = 1;	// a就是一个左值
  • 右值

右值是那些不能被取地址、只能读取的数据。

右值通常包括常量、表达式结果、字符串字面量和临时变量(传值返回的函数返回值)等。

右值出现在赋值语句中的右边,计算得到某个数值或数据,再赋给左值。

int x = 1, y = 2;		//1、2是右值
int a = x + y;			//(x + y) 是右值
string name = "yyjs";	//"yyjs"是右值

左值引用和右值引用

    C++11新特性 本质上都是进行取别名

  • 左值引用

&符号表示,可以绑定到一个左值,因为它们都可取地址

int a = 1;
int &ref_a = a; // 左值引用
  • 右值引用

&&符号表示,只能绑定到一个右值(临时变量、表达式、字面量等)

int &&rr1 = 1; 	// 右值引用
double&& rr2 = 1.2 + 2.9;

值得一提的是对于右值引用,如rr1、rr2。它们给右值取别名后,会分配特定的存储空间,通过右值引用,可以取地址,可以被修改。使用const修饰右值引用,禁止修改。

  • const左值引用

左值引用不能引用右值,右值是临时的、不可修改的。不能将权限放大

const左值引用可以引用右值,保证数据不会修改

void show(const string& str)
{
    cout << str << endl;
}
int main
{
    show("12345");//使用右值传参
}
  • move()

被move后的左值能够赋值给右值引用

int a = 1;
//int &&rr2 = a; error
int &&rr2 = std::move(a); 

使用

左值引用

我们通常使用左值引用作为参数返回值

void func1(const string& s){}
string& get(){}

都是为了减少(深)拷贝的消耗,提高效率


短板:但是当函数返回对象是一个局部变量 ,出了函数作用域就不存在了,就不能使用左值引用返回,只能传值返回。

string iTos(int value)
{
    string str;
    ...
    return str;
}
string s = iTos(123);

在这里插入图片描述

右值引用和移动语义

来解决左值引用的短板,提高效率

如果在string类中增加

移动构造函数

class string
{
public:
	// s1.swap(s2)
	void swap(string& s)
	{
		::swap(_str, s._str);
		::swap(_size, s._size);
		::swap(_capacity, s._capacity);
	}

	// 移动构造
	string(string&& s)
		:_str(nullptr)
		, _size(0)
		, _capacity(0)
	{
		swap(s);
	}
	。。。
private:
	char* _str;
	size_t _size;
	size_t _capacity; // 不包含最后做标识的\0
};

对于iTos()的使用,调用到移动构造。

string s = iTos(123);

在这里插入图片描述

    对于s的创建调用的是其构造函数。iTos()的返回值string对象是一个“将亡值”,即将消耗的对象。编译器会进行识别,并且调用string的移动构造函数string(string&& s){},函数内通过swap()将资源进行转移,从而避免深拷贝的消耗。

移动赋值

// 移动赋值
string& operator=(string&& s)
{
    swap(s);
    return *this;
}
string s;
s = iTos(123);//调用移动赋值

同理

move()

string s1("hello today~");
string s3 = std::move(s1);

同理,s1的资源通过右值引用,移动构造转移给了s3,并且s1为空。

完美转发

万能引用

模板中,&&符号代表万能引用,既能接收左值又能接收右值

template <class T>
void PrefectForward(T&& t) {}

在这里插入图片描述

右值被引用之后会被储存到特定的位置,而这个储存位置在函数参数中是可以被取地址和修改的,因此实际上已经退化为左值了

如果想在万能引用中保持右值属性,就需要完美转发

完美转发

要想在参数传递过程中保持其原有的属性,需要在传参时调用,forward()函数

template<class T>
void PerfectForward(T&& t)
{
	func(std::forward<T>(t));
}

在这里插入图片描述

完美转发在传参的过程中保留对象原生类型属性

使用示例:

template<class T>
struct ListNode
{
	T _data;
	ListNode* _next = nullptr;
	ListNode* _prev = nullptr;
};
template<class T>
class list
{
	typedef ListNode<T> node;
public:
    。。。
	// 右值引用版本
	void push_back(T&& x)
	{					//完美转发
		insert(_head, std::forward<T>(x));
	}
    
	// 右值引用版本
	void insert(node* pos, T&& x)
	{
		node* prev = pos->_prev;
		node* newnode = new node;
       //完美转发,同时会去调用T类的移动构造函数(如果有)
		newnode->_data = std::forward<T>(x);

		prev->_next = newnode;
		newnode->_prev = prev;
		newnode->_next = pos;
		pos->_prev = newnode;
	}
private:
	node* _head;
};
list<string> lt;
lt.push_back("world");//右值

    🦀🦀观看~~

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

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

相关文章

rabbitmq安装步骤和遇到的问题

一、安装准备工具 1.下载Eralng&#xff0c;下面链接已提供otp_win64_20.2.exe 链接&#xff1a; https://pan.baidu.com/s/1lmvCMPVAV1Ba9UogCdQpZg 提取码&#xff1a;x9m7 2.下载rabbitmq&#xff0c;下面链接已提供rabbitmq-server-3.7.4.exe 链接&#xff1a; https:…

CentOS安装supervisor管理rocketmq进程

一、supervisor 介绍 Supervisor 翻译过来是监管人&#xff0c;在 Linux 中 Supervisor 是一个进程管理工具&#xff0c;当进程中断的时候 Supervisor 能自动重新启动它。可以运行在各种类 Linux/unix 的机器上&#xff0c;supervisor 就是用 Python 开发的一套通用的进程管理程…

【Qt】随记2:CV_Assert的用法

欢迎阅读本博文&#xff0c;本文主要记录Qt学习、工作中的一些注意点及相关笔记&#x1f4c3; 希望记录的内容有帮助到你&#xff0c;也欢迎把你知道的分享给大家&#xff0c;一起进步&#xff01;&#x1f389; 喜欢的话&#xff0c;请帮忙点赞&#x1f44d;、评论&#x1f4…

STM32开发指南:逐步揭开嵌入式世界的奥秘

想要深入嵌入式开发领域&#xff1f;掌握STM32这本"天书"&#xff1f;也许你觉得它难以捉摸&#xff0c;但是别担心&#xff01;我们为你准备了一份简洁明了的指南&#xff0c;将带你逐步解读STM32的奥秘。 首先&#xff0c;我们将介绍STM32的基础知识。从了解STM32…

自学黑客(网络安全),一般人我劝你还是算了吧(自学网络安全学习路线--第六章 身份认证与访问控制)【建议收藏】

文章目录 一、自学网络安全学习的误区和陷阱二、学习网络安全的一些前期准备三、自学网络安全学习路线一、身份认证1、身份认证概述2、身份认证常用技术3、常用身份认证机制 二、访问控制1、访问控制概述2、访问控制基本要素 三、访问控制类型四、访问控制机制 一、自学网络安全…

git 常见错误解决

一、git命令运行时出现以下错误提示&#xff1a; git add -A fatal: detected dubious ownership in repository at D:/****/WWW/www.***.cc D:/**/WWW/www.**.cc is owned by:S-1-5-32-544 but the current user is:S-1-5-21-4097290046-3821524887-*****-1001 To add an exce…

B站 Java相关学习资源汇总

一、计算机网络 计算机网络微课堂 https://www.bilibili.com/video/BV1c4411d7jb?p1 讲师&#xff1a;湖科大教书匠 评价&#xff1a;通俗易懂&#xff0c;重点知识十分细致&#xff0c;配合实验&#xff0c;而且有考研408 的难题的讲解&#xff0c;也是非常适合考研党&#…

QT树的实现

理论 在Model/View结构中&#xff0c;数据模型为视图组件和代理组件提供存取数据的标准接口。在QT中&#xff0c;所有的数据模型类都从QAbstactItemModel继承而来&#xff0c;不管底层的数据结构是如何组织数据的&#xff0c;QAbstractItemModel的子类都以表格的层次结构表示数…

Qt中多线程的使用

前言 在进行桌面应用程序开发的时候&#xff0c; 假设应用程序在某些情况下需要处理比较复杂的逻辑&#xff0c; 如果只有一个线程去处理&#xff0c;就会导致窗口卡顿&#xff0c;无法处理用户的相关操作。这种情况下就需要使用多线程&#xff0c;其中一个线程处理窗口事件&a…

快速幂的理解、leetcode剑指 Offer 16. 数值的整数次方解析

0、引言 算法小计&#xff1a;本文阐述以下自己对于快速幂的理解&#xff0c;之前想了很久没想通。 对于求一个数字a的n次方问题&#xff1a;&#xff0c;如果直接写循环&#xff0c;从1开始每次乘以a&#xff0c;求n次即可做出答案&#xff0c;但时间复杂度是O(n)&#xff0c…

陌陌聊天数据分析 (二)

陌陌聊天数据分析 &#xff08;二&#xff09; &#x1f3c6;FineBI构建连接 陌陌聊天数据分析 &#xff08;一&#xff09; 新建连接 配置连接 测试连接并保存 &#x1f3c5;数据准备 新建分组 添加业务包 添加表 &#x1f948;构建可视化报表 &#x1f3c8;添加…

国内好用的五款低代码平台,你用的哪一款?

随着信息化技术的发展&#xff0c;软件开发领域也在不断更新迭代&#xff0c;在企业数字化升级的浪潮中&#xff0c;低代码平台的应用也越来越广泛。从业务系统到办公软件&#xff0c;从 BI分析到移动开发&#xff0c;越来越多的企业和IT团队开始使用低代码平台来构建数字化应用…

【Nginx】第六章 Nginx配置实例-动静分离

Nginx 动静分离简单来说就是把动态跟静态请求分开&#xff0c;不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开&#xff0c;可以理解成使用Nginx 处理静态页面&#xff0c;Tomcat处理动态页面。动静分离从目前实现角度来讲大致分…

超分布检测中的平衡能量正则化损失

文章目录 Balanced Energy Regularization Loss for Out-of-distribution Detection摘要本文方法Balanced Energy regularization loss 实验结果 Balanced Energy Regularization Loss for Out-of-distribution Detection 摘要 在超分布(out of distribution, OOD)检测领域&a…

express 获取阿里云 oss 文件对象列表

使用 ali-oss 包 pnpm add ali-oss -S 创建 oss 实例&#xff0c;并拉取数据 阿里云 oss 返回示例&#xff1a;

一种接口依赖关系分层方案 | 京东云技术团队

1、背景 到店商详迭代过程中&#xff0c;需要提供的对外能力越来越多&#xff0c;如预约日历、附近门店、为你推荐等。这其中不可避免会出现多个上层能力依赖同一个底层接口的场景。最初采用的方案是对外API入口进来后获取对应的能力&#xff0c;并发调用多项能力&#xff0c;…

【Vue】组件高级

文章目录 组件高级一、watch 监听器二、组件的生命周期2.1 组件运行的过程2.2 监听组件的不同时刻2.3 监听组件的更新2.4 主要生命周期函数 三、组件之间的数据共享3.1 组件关系及数据共享3.2 父子组件数据共享3.3 兄弟组件数据共享3.4 后代组件数据共享3.5 vuex 四、全局配置 …

基于Thinkphp6框架全新UI的AI网址导航系统源码

✨ 源码介绍 2023全新UI的AI网址导航系统源码&#xff0c;基于thinkphp6框架开发的 AI 网址导航是一个非常实用的工具&#xff0c;它能够帮助用户方便地浏览和管理自己喜欢的网站。 相比于其他的 AI 网址导航&#xff0c;这个项目使用了更加友好和易用的 ThinkPHP 框架进行搭建…

基于3×3耦合器的干涉型光纤传感器信号解调技术研究-Matlab代码

一、引言 光纤耦合器是一种使光信号在特殊结构的耦合区内发生耦合&#xff0c;将功率再分配的无源器件。它在光纤传感和光通信等领域有着广泛的应用&#xff0c;在耦合过程中&#xff0c;光信号的频谱成分不变&#xff0c;只是信号的光功率发生变化。1980年&#xff0c;K&…

2023双态IT北京用户大会回顾(二) | 云内外一体化智能监控构建之路

文末附有本场专题演讲视频 2023第五届双态IT北京用户大会擎创科技专场演讲回顾&#xff08;二&#xff09;&#xff1a;《云内外一体化智能监控构建之路》演讲嘉宾&#xff1a;擎创科技产品线总监 殷传旺 一、前言&#xff1a;企业运维自然推进or独立发展&#xff1f; 我们从…