C++11右值引用的价值体现

前言

好久之前就写了一篇文章:谈谈C++中的左值,右值,右值引用,std::move()的问题是理解移动构造和移动赋值的前提基础;
这里简单总结一下:

  • 左值特点
  • 获取地址+可对它赋值;
  • 但是对于const 的变量,它可以取地址,但是不能对它赋值;
  • 左值只会出现赋值符号的左边,当然也可以出现在赋值符号右边;
    在这里插入图片描述

  • 右值特点
  • 右值不可以取地址
  • 右值不可以出现赋值符号的左边,只能出现在赋值符号的右边;
  • 常见的右值:常量,数据表达式,传值的函数返回值;临时对象,即将销毁的值(一般都是函数返回值);
    在这里插入图片描述

  • 右值引用后,可以对右值引用这个变量取地址,并且赋值,本质上右值引用单独这个变量就是左值!
    在这里插入图片描述

左值右值交叉引用

左值引用不能直接引用右值;
左值引用要引用右值,需要加const修饰左值引用;
右值也不可以直接引用左值;
右值要引用左值需要加std::move()函数修饰左值;
在这里插入图片描述


在这里插入图片描述


右值引用的价值体现的地方

首先明确一点:右值引用的产生就是为了弥补左值引用的不足!
所以先回顾一下,左值引用的价值体现在哪,它的不足又体现在哪;

左值引用的第一个价值体现常见就是:

  1. 做函数的参数,可以减少拷贝形参(减少函数形参调用了拷贝构造)这个步骤;
  2. 做函数的返回值,只要这个变量出了作用域还在,那么就可以用左值引用接收该返回值;为什么用左值引用左函数返回值?因为可以减少一次拷贝(我们知道函数返回值,如果不用引用接收,那么就会用返回值作为实参去拷贝构造一个临时对象);

左值引用的问题就在于做函数的返回值,它只能解决变量出作用域还在在的场景,不能解决出了作用域不在的变量场景(为什么不行?局部变量出了作用域,函数栈帧销毁,引用的到返回值也是随机值);

基于这个原因:C++11搞出了一个右值引用去解决:函数返回值,左值引用不能引用局部变量的问题;也就是以值返回的函数,存在拷贝构造问题

注意:解决的方式不是直接给函数返回值从左值引用改为为右值引用,而是通过增加移动构造去解决这个问题!

所以说:原来函数是传值返回的,依旧传值返回!同时给该传值返回的对象类中,增加一个移动构造,就会解决这个问题(这个问题就是左值引用不可以解决局部对象做返回值会拷贝的临时变量的问题);


移动构造 移动复制

既然局部变量的值做返回值,不可以直接左值引用,那么我们可以在它即将销毁前,移动它的资源过去给函数返回;相当于,人死了之前,会留下丰富的遗产给她女儿儿子一样;


在这里插入图片描述


一般编译器会有优化;它会在调用该函数时候,看到,假如没有接收函数返回值,那么就会拷贝临时对象,假如有接收那么就会拿str直接拷贝构造 调用该函数时候的接收返回值的对象;
移动构造同理;移动构造会把即将销毁的变量看出右值,所以说,会调用移动构造;


函数返回值的拷贝构造临时对象存放在哪?必然在调用该函数的栈帧中;


移动赋值同理;

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呋喃吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值