左值&右值
一、引子
我们所谓的左值、右值,正确的说法应该是左值表达式、右值表达式。
因为C++的表达式不是左值就是右值。
在C中,左值指的是既能够出现在等号左边也能出现在等号右边的表达式,右值指的则是只能出现在等号右边的表达式。
而在C++中,二者的区别就不是这么简单了。
二、关键点
【官方定义】
- 一个左值表达式的求值结果是一个对象或者一个函数,而某些右值表达式的求值结果也是对象;
- 以常量对象为代表的某些左值并不能作为赋值语句的左侧运算对象。
- 归纳:当一个对象被用作右值的时候,用的是对象的值(内容);而被用作左值的时候,用的是对象的身份(在内存中的位置)。
【解读定义】
解读第一句:既然左值和右值都可以是对象,那怎么区分一个对象是左值还是右值呢?
- 左值:能用“取地址&”运算符获得对象的内存地址
- 右值:不能用“取地址&”运算符获得对象的内存地址
- 特例:因为可以用&取得字符串字面值常量的地址,所以它是一个左值;而其他的字面值常量则不可用&取地址,所以它们是右值
我们知道对象是一块空间,那么有哪些对象以及为什么不能用&取地址呢?
- 对于临时对象,它可以存储于寄存器中,所以没办法用“取地址&”运算符;
- 对于(非字符串)常量,它可能被编码到机器指令的“立即数”中,所以没办法用“取地址&”运算符。
解读第二句:字符串字面值常量确实不能放在等号左边啊,没错啊!
解读归纳:所以啊,左值看地址,右值看内容。
【补充】
#include <iostream> using namespace std; int& func(int &a)
{
return a; // 不能返回局部对象的引用
} int main()
{
int a = 10;
func(a) = 100; // 返回非常量引用的函数可以当作左值使用
cout << a << endl; // 输出100
return 0;
}
三、为什么要区分左值右值
- 不同的运算符对运算对象的要求各不相同,有的需要左值运算对象、有的需要右值运算对象;返回值也有差异,有的得到左值结果、有的得到右值结果。
举例:使用关键字decltype的时候,其表达式的求值结果若是左值,decltype作用于该表达式(不能是变量)得到一个引用类型。例如,p的类型是int *,因为解引用运算符生成左值,所以decltype(*p)的结果是int &。而另一方面,因为取地址运算符生成右值,所以decltype(&p)的结果是int **,即结果是一个指向整型指针的指针。
左值&右值的更多相关文章
- c++ 左值右值 函数模板
1.先看一段代码,这就是一种函数模板的用法,但是红色的部分如果把a写成a++或者写成一个常量比如1,都是编译不过的,因为如果是a++的话,实际上首先是取得a的 值0,而0作为一个常量没有地址.写成1也 ...
- C++ 左值 右值
最近在研究C++ 左值 右值,搬运.收集了一些别人的资料,供自己记录和学习,若以后看到了更好的解释,会继续补充.(打“?”是我自己不明白的地方 ) 参考:<Boost程序库探秘——深度解析C ...
- C++ 左值与右值 右值引用 引用折叠 => 完美转发
左值与右值 什么是左值?什么是右值? 在C++里没有明确定义.看了几个版本,有名字的是左值,没名字的是右值.能被&取地址的是左值,不能被&取地址的是右值.而且左值与右值可以发生转换. ...
- C++11之右值引用(一):从左值右值到右值引用
C++98中规定了左值和右值的概念,但是一般程序员不需要理解的过于深入,因为对于C++98,左值和右值的划分一般用处不大,但是到了C++11,它的重要性开始显现出来. C++98标准明确规定: 左值是 ...
- C语言几个术语: 数据对象,左值,右值
1. 数据对象 赋值表达式语句的目的是把值存储到内存位置上. 用于存储值的数据存储区域统称为数据对象. 2. 左值 左值是C语言的术语, 用于标识特定数据对象的名称或表达式. 对象指的是实际的数据存储 ...
- i++和++i以及左值,右值
左值(LValue)和右值(RValue)的一个快捷记法是赋值运算,左值是赋值运算左边的值,右值就是右边(=,=废话).例如: int a = 5; a就是左值,5就是右值. 当然,如果真是这么个含义 ...
- C和C指针小记(八)-操作符、左值右值
1.移位操作符 移位操作符分为左移操作符(<<)和右移操纵符(>>) 对于无符号数:左右位移操作都是逻辑位移 对于有符号数:到底是采用逻辑位移还是算术位移取决于编译器.如果一个 ...
- C++中的左值与右值(二)
以前以为自己把左值和右值已经弄清楚了,果然发现自己还是太年轻了,下面的这些东西是自己通过在网上拾人牙慧,加上自己的理解写的. 1. 2. 怎么区分左值和右值:知乎大神@顾露的回答. 3. 我们不能直接 ...
- C语言 左值、右值
左值就是在赋值中可以放在赋值操作符两边的值 右值则是只可以放在赋值操作符右边的值 ++i是直接给i变量加1,然后返回i本身,因为i是变量,所以可以被赋值,因此是左值表达式i++现产生一个临时变量,记录 ...
随机推荐
- Zabbix——设置模板
前提条件: Zabbix版本为4.0 可以正常使用Server 1. 添加H3C网络交换机的CPU和内存模板,并配置自动发现. 注意,需要添加完成后,重新进行搜索后再此进入才有下列选项. 添加CPU的 ...
- MySQL---视图、触发器
一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( S ...
- HTML5中的拖拽与拖放(drag&&drop)
1.drag 当拖动某个元素时,将会依次触发下列事件: 1)dragstart:按下鼠标键并开始移动鼠标时,会触发该事件 2)drag:dragstart触发后,随即便触发drag事件,而且在元素被拖 ...
- Currency Helper
using System; using Microsoft.Xrm.Sdk; using Microsoft.Crm.Sdk.Messages; /// <summary> /// 货币 ...
- Python-入门必备
·Python入门必备 @ 交互式编程 交互式编程不需要创建脚本文件,而是直接通过Python解释器的交互模式进来编写代码.下面我们来打开python自带的交互式编程客户端,打印一个hello,wor ...
- linux (ubuntu)安装pycharm
1. 下载 http://www.jetbrains.com/pycharm/download/ 选择Linux Tab,选择下载免费的Community Edition. 2. 安装PyCharm ...
- Caliburn.Micro 杰的入门教程6, Screens 和 Conductors 简介
Caliburn.Micro 杰的入门教程1(翻译)Caliburn.Micro 杰的入门教程2 ,了解Data Binding 和 Events(翻译)Caliburn.Micro 杰的入门教程3, ...
- CF 1042 F. Leaf Sets
F. Leaf Sets http://codeforces.com/contest/1042/problem/F 题意: 将所有的叶子节点分配到尽量少的集合,一个可行的集合中两两叶子节点的距离< ...
- CDN 缓存策略(转)
1.CDN加速原理 通过动态域名解析,网友的请求被分配到离自己最快的服务器.CDN服务器直接返回缓存文件或通过专线代理原站的内容. 网络加速+内容缓存,有效提供访问速度 2.CDN节点数量 ...
- C# Builder
如下: class Program { static void Main(string[] args) { ).BuildB(2.1).BuildUp(); Console.Read(); } } p ...