右值,右值引用,move,forward

  • 区分左值和右值

一个最为典型的判别方法就是,在赋值表达式中,出现在等号左边的就是“左值”,而在等号右边的,则称为“右值”。

还有一个说法,就是可以取地址的、有名字的就是左传,反之,不能取地址的、没有名字的就是右值。

右值又分将亡值(xvalue),纯右值。

  • 引用

引用类型本身自己并不拥有所绑定对象的内存,只是该对象的一个别名。

  • 右值引用

右值引用标记为T&&

用右值引用变量声明,会少一次对象的构造及一次对象的析构。

好处:减少内存拷贝,避免无谓的复制,提高程序性能。

左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。

总结:

(1)左值和右值是独立于它们的类型,右值引用类型可能是左值也可能是右值

(2)auto&&或函数参数类型的自动推导的T&&是一个未定的引用类型,它可能是左值引用,也可能是右值引用,取决于初始化的值类型

(3)所有的右值引用叠加到右值引用上仍然是一个右值引用,其它引用叠加都为坐值引用,当T&&为模版参数时,输入左值,它会变为左值引用,输入右值则变为具名的右值引用

(4)编译器会将已命名的右值引用视为左值,而将未命名的右值视为右值

  • move

移动语义是通过右值引用来匹配临时值的

有些左值是局部变量,生命周期也很短,能不能也移动而不是拷贝呢?

C++11提供了std::move()方法来将左值转换为右值,从而方便应用移动语义。

move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转义,没有内存拷贝。

MyString str1 = "hello";
MyString str2(str1);
MyString str3 = Fun();
MyString str4 = move(str2);

注:

  1. 如果我们没有提供移动构造函数,只提供了拷贝构造函数,std::move()会失效但是不会发生错误,因为编译器找不到移动构造函数就去寻找拷贝构造函数,也这是拷贝构造函数的参数是const T&常量左值引用的原因!
  2. c++11中的所有容器都实现了move语义,move只是转移了资源的控制权,本质上是将左值强制转化为右值使用,以用于移动拷贝或赋值,避免对含有资源的对象发生无谓的拷贝。move对于拥有如内存、文件句柄等资源的成员的对象有效,如果是一些基本类型,如int和char[10]数组等,如果使用move,仍会发生拷贝(因为没有对应的移动构造函数),所以说move对含有资源的对象说更有意义。
  • forward

所谓转发,就是通过一个函数将参数继续转交给另一个函数进行处理,原参数可能是右值,可能是左值,并且保持参数的原有特征。

MyString str1 = "hello";
MyString str2(str1);
MyString str3 = Fun();
MyString str4 = move(str2);
MyString str5(forward<MyString>(str3));

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

子建莫敌

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

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

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

打赏作者

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

抵扣说明:

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

余额充值