0 左值和右值

    一个左值表达式代表的是对象本身,而右值表达式代表的是对象的值;变量也是左值。
 

1 右值引用作用

为了支持移动操作(包括移动构造函数和移动赋值函数),C++才引入了一种新的引用类型——右值引用,可以自由接管右值引用的对象内容。

2 右值引用绑定的对象

    返回非引用类型的函数,产生右值的表达式(算术表达式、关系表达式、位、后置递增递减)
 

3 和左值引用的区别

  1. 绑定的对象(引用的对象)不同,左值引用绑定的是返回左值引用的函数、赋值、下标、解引用、前置递增递减
  2. 左值持久,右值短暂,右值只能绑定到临时对象,所引用的对象将要销毁或该对象没有其他用户
  3. 使用右值引用的代码可以自由的接管所引用对象的内容

清单1

 int &&i = ;
int b = ;
cout << i << endl;
i = b;
cout << i << endl;
//输出1 2
清单1中i绑定到了右值1,说明:初始化时,右值引用一定要用一个右值表达式绑定;初始化之后,可以用左值表达式修改右值引用的所引用临时对象的值
 

清单2:清单1反汇编

;省略上面代码
int &&i = ;
00C044DE mov dword ptr [ebp-14h],
00C044E5 lea eax,[ebp-14h]
00C044E8 mov dword ptr [ebp-],eax
int b = ;
00C044EB mov dword ptr [ebp-20h],
;省略输出代码
i = b;
00C04523 mov eax,dword ptr [ebp-]
00C04526 mov ecx,dword ptr [ebp-20h]
00C04529 mov dword ptr [eax],ecx
;省略余下代码
清单2可以清楚看出右值引用的底层实现。第3行对一个临时变量赋值0,第4-5行将临时变量地址存储至i中,因此i存储的实际是临时对象的地址(也就是对临时对象的一种引用)。
第10行mov  eax,dword ptr [ebp-8]取出了i存储的数据(临时对象地址),11-12行将b变量的值赋值到临时对象,而i存储的数据不变,仍是存储临时对象的地址(也就是对临时对象的一种引用)。
 

清单3:右值引用变量也是左值

 int&&temp =;
int&&i = temp;
清单3中temp是一个右值引用变量,变量是左值,因此i引用temp左值是非法的!
 

清单4:右值引用赋值右值引用

 int &&temp = ;
int &&i = ;
i = temp;
清单4是合法的,取出temp所引用临时对象的值,再赋值给i所引用临时对象的值。
 

清单5

 class A{
public:
int b;
int a;
char c[];
};
void f(A a)
{
;
}
int main(int argc, char const *argv[])
{
A &&a = A();
f(a);
}
清单5是合法的,过程符合一般逻辑,即会生成a引用临时对象的一个副本,再传入副本对象的地址。如果f函数的形参是引用类型的,那么调用f函数传入的是a引用对象的地址,而不会生成副本
 

4 总结

  1. 右值引用,是对临时对象的一种引用,它是在初始化时完成引用的,但是右值引用不代表引用临时对象后就不能改变右值引用所引用对象的值,仍然可以在初始化后改变临时对象的值。
  2. 对于引用类型,可以用于它所引用对象类型的可以用的地方(把它当成普通变量),只不过用到的值是它所引用的对象的值,它还可以用于移动构造或赋值函数的地方。

本文链接:【原创】深入理解c++的右值引用http://www.cnblogs.com/cposture/p/4927712.html

【原创】深入理解c++的右值引用的更多相关文章

  1. C++左值引用与右值引用

    本文翻译自:https://docs.microsoft.com/en-us/cpp/cpp/references-cpp?view=vs-2019 引用,类似于指针,用于存储一个位于内存某处的对象的 ...

  2. 【转】C++ 11 右值引用的理解

    右值引用的目的之一,是为了C++中一个比较影响性能的问题:拷贝临时对象,例如,在 int foo(){ ... } int x; x = foo(); 中,在第三句中,发生了以下的事情: 1.销毁 x ...

  3. std::move的原理与实现,右值引用的深入理解

    这次我真的懂了.... 首先C++11引入了右值引用 && ‘&&’这个要连起来看,是一个整体,C++多了一个关键字而已. 不是引用的引用.是船新的一种语法.那有什么用 ...

  4. [转][c++11]我理解的右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  5. 透彻理解C++11新特性:右值引用、std::move、std::forward

    目录 浅拷贝.深拷贝 左值.右值 右值引用类型 强转右值 std::move 重新审视右值引用 右值引用类型和右值的关系 函数参数传递 函数返还值传递 万能引用 引用折叠 完美转发 std::forw ...

  6. (原创)C++11改进我们的程序之右值引用

    本次主要讲c++11中的右值引用,后面还会讲到右值引用如何结合std::move优化我们的程序. c++11增加了一个新的类型,称作右值引用(R-value reference),标记为T & ...

  7. C++11_ 右值引用

    版权声明:本文为博主原创文章,未经博主允许不得转载. 由于右值所产生的临时变量问题一直是一种诟病,C++11中引入了右值引用这个核心语言机制,来提升运行期性能. 首先我先说明一下什么是左值和右值: 左 ...

  8. 对C++11中的`移动语义`与`右值引用`的介绍与讨论

    本文主要介绍了C++11中的移动语义与右值引用, 并且对其中的一些坑做了深入的讨论. 在正式介绍这部分内容之前, 我们先介绍一下rule of three/five原则, 与copy-and-swap ...

  9. C++右值引用浅析

    一直想试着把自己理解和学习到的右值引用相关的技术细节整理并分享出来,希望能够对感兴趣的朋友提供帮助. 右值引用是C++11标准中新增的一个特性.右值引用允许程序员可以忽略逻辑上不需要的拷贝:而且还可以 ...

随机推荐

  1. 小白的CTF学习之路5——内存的逻辑结构

    很衰的一天,各种意料之外的问题,但都挡不住我每日一更的步伐 内存的逻辑结构大致分为以下几种: 数组 栈与队列 链表 二叉树 以上,数组,栈,链表是我这章要说明的 在学习前需要了解的两个问题: 1.内存 ...

  2. Web缓存和静态化

    Web缓存和静态化 目录 Web缓存基础... 1 什么是Web缓存... 1 Web缓存的类型... 1 为何要使用Web缓存... 1 重验证... 1 更新... 2 浏览器缓存... 2 工作 ...

  3. 无法获得锁 /var/lib/dpkg/lock - open

    关于 apt-get update 更新的时候出现 无法获得锁 /var/lib/dpkg/lock - open 解决 直接删除这个锁文件即可: sudo rm /var/lib/dpkg/lock ...

  4. flag读取控制台参数

    package main import ( "fmt" "os") func main() { arg := os.Args if len(arg) < ...

  5. java操作FTP的一些工具方法

    java操作FTP还是很方便的,有多种开源支持,这里在apache开源的基础上自己进行了一些设计,使用起来更顺手和快捷. 思路: 1.设计FTPHandler接口,可以对ftp,sftp进行统一操作, ...

  6. mpvue 初体验之改写车标速查小程序

    前文 说到我开发了一个简单的小程序叫做 车标速查(代码以及二维码详见 这里),本文简单讲讲如何将这个小程序转为 mpvue 开发(最终 成果 ) mpvue 官网的 文档 真的是非常简单,不,应该说是 ...

  7. require()  module.export    Object.keys()

    import API from"../../api/api.js";   var data = require('../../utils/data.js').songs;   // ...

  8. python2 python3区别(续)

    1.除法 Python2 Python3 int/int → int int/int → float python2下整数除以整数返回整数类型,python3下整数除以整数返回浮点数类型 当某些语句假 ...

  9. windows putty xming virt-manager

    记一次windows环境使用linux下使用virt-manager软件的问题 环境:windows server 2008.ubuntu-server 软件:putty.virt-manager.x ...

  10. 可参数化的带优先级的数据选择器的FPGA实现方式探讨

    在FPGA设计中,大部分情况下我们都得使用到数据选择器.并且为了设计参数化,可调,通常情况下我们需要一个参数可调的数据选择器,比如M选1,M是可调的参数. 如果,数据选择器是不带优先级的,我们可以使用 ...