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

[转]C++11 左值、右值、右值引用详解

https://blog.csdn.net/hyman_yx/article/details/52044632

左值、右值

在C++11中所有的值必属于左值、右值两者之一,右值又可以细分为纯右值、将亡值。在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。举个例子,int a = b+c, a 就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变量名找到它,&(b+c)这样的操作则不会通过编译。

右值、将亡值

在理解C++11的右值前,先看看C++98中右值的概念:C++98中右值是纯右值,纯右值指的是临时变量值、不跟对象关联的字面量值。临时变量指的是非引用返回的函数返回值、表达式等,例如函数int func()的返回值,表达式a+b;不跟对象关联的字面量值,例如true,2,”C”等。

C++11对C++98中的右值进行了扩充。在C++11中右值又分为纯右值(prvalue,Pure Rvalue)和将亡值(xvalue,eXpiring Value)。其中纯右值的概念等同于我们在C++98标准中右值的概念,指的是临时变量和不跟对象关联的字面量值;将亡值则是C++11新增的跟右值引用相关的表达式,这样表达式通常是将要被移动的对象(移为他用),比如返回右值引用T&&的函数返回值、std::move的返回值,或者转换为T&&的类型转换函数的返回值。

将亡值可以理解为通过“盗取”其他变量内存空间的方式获取到的值。在确保其他变量不再被使用、或即将被销毁时,通过“盗取”的方式可以避免内存空间的释放和分配,能够延长变量值的生命期。

左值引用、右值引用

左值引用就是对一个左值进行引用的类型。右值引用就是对一个右值进行引用的类型,事实上,由于右值通常不具有名字,我们也只能通过引用的方式找到它的存在。

右值引用左值引用都是属于引用类型。无论是声明一个左值引用还是右值引用,都必须立即进行初始化。而其原因可以理解为是引用类型本身自己并不拥有所绑定对象的内存,只是该对象的一个别名。左值引用是具名变量值的别名,而右值引用则是不具名(匿名)变量的别名。

左值引用通常也不能绑定到右值,但常量左值引用是个“万能”的引用类型。它可以接受非常量左值、常量左值、右值对其进行初始化。不过常量左值所引用的右值在它的“余生”中只能是只读的。相对地,非常量左值只能接受非常量左值对其进行初始化。

int &a = 2;       # 左值引用绑定到右值,编译失败

int b = 2; # 非常量左值 const int &c = b; # 常量左值引用绑定到非常量左值,编译通过 const int d = 2; # 常量左值 const int &e = c; # 常量左值引用绑定到常量左值,编译通过 const int &b =2; # 常量左值引用绑定到右值,编程通过
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

右值值引用通常不能绑定到任何的左值,要想绑定一个左值到右值引用,通常需要std::move()将左值强制转换为右值,例如:

int a;
int &&r1 = c;             # 编译失败
int &&r2 = std::move(a); # 编译通过
  • 1
  • 2
  • 3

下表列出了在C++11中各种引用类型可以引用的值的类型。值得注意的是,只要能够绑定右值的引用类型,都能够延长右值的生命期。
这里写图片描述

参考资料

《深入理解C++11:C++11新特性解析与应用》
http://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion-return-statement

--------------------- 本文来自 hyman_yx 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/hyman_yx/article/details/52044632?utm_source=copy 

相关文章:

  • MySQL定时检查是否宕机并邮件通知
  • Win10常用优化技巧汇编
  • 记一次对Vulnerable Docker靶机渗透全过程
  • linux命令行快捷键
  • 第十七章:掌握网格(三)
  • 现代软件工程 期中/期末总结博客作业
  • [转]CentOS 6.5安全加固及性能优化
  • NDK编译可执行文件
  • TCP协议学习总结(上)
  • cocos2dx 屏幕触摸
  • js 属性getset
  • PHP之curl put方式提交与接受数据
  • [Android Pro] AndroidX重构和映射
  • Eclipse SVN插件检出Src下面的包变成了文件夹解决
  • 科学家研发出3D打印韧带 使用电力来制造纤维
  • 2018天猫双11|这就是阿里云!不止有新技术,更有温暖的社会力量
  • Android框架之Volley
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • eclipse的离线汉化
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • HTTP中GET与POST的区别 99%的错误认识
  • isset在php5.6-和php7.0+的一些差异
  • java2019面试题北京
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Spark学习笔记之相关记录
  • Spring-boot 启动时碰到的错误
  • SpriteKit 技巧之添加背景图片
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • zookeeper系列(七)实战分布式命名服务
  • 分享一份非常强势的Android面试题
  • 计算机在识别图像时“看到”了什么?
  • 区块链分支循环
  • 双管齐下,VMware的容器新战略
  • 思考 CSS 架构
  • ​插件化DPI在商用WIFI中的价值
  • # centos7下FFmpeg环境部署记录
  • #### go map 底层结构 ####
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • (2)STL算法之元素计数
  • (4.10~4.16)
  • (day 12)JavaScript学习笔记(数组3)
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)Linux——Linux常用指令
  • (二)WCF的Binding模型
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (一) storm的集群安装与配置
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)大型网站的系统架构
  • (转)详解PHP处理密码的几种方式
  • /proc/vmstat 详解
  • [2018/11/18] Java数据结构(2) 简单排序 冒泡排序 选择排序 插入排序
  • [2019/05/17]解决springboot测试List接口时JSON传参异常