C++ lvalue(左值)和rvalue(右值)
lvalue(左值)和rvalue(右值)
昨天写代码遇见一个这样的错误:{ "cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’",代码类似下边
class MyClass {
int data;
public:
MyClass(int& e):data(e){};
};
int main(){
MyClass c(10);
return 0;
}
编译器告诉我们:“不能将非const的lvalue引用 和 rvalue绑定”,里边有两个关键词:lvalue和rvalue。
什么是lvalue(左值)
简单定义:内存中有确定存储地址的对象的表达式的值,可以是一个变量名:int a;,可以是一个赋值表达式a=b,或者字符串常量"cnblogs",总之,最简单鉴别的方法就是编译以下这个句子&(需要鉴别的表达式),能通过编译就是左值。
严格定义见:C++文档
左值有什么性质?
可以被取地址(&),上边我们就是用这个方法来鉴别左值。
可以被赋值,或者复制赋值;
//赋值
int a = 10;
//复制赋值
int a(10);
可以初始化左值引用,也就是我们常用的引用;
int a=10;
int& reference = a;
这是一些常用的性质,更多性质见:C++文档
什么是rvalue(右值)
:非左值。
常见的有字面值(除了字符串常量),后置自增自减表达式a++;a--;
右值有什么性质?
不能被取地址
int a = 1;
int* p = &(a++); //报错,a++是右值,不能被取地址,而++a是左值
不能被赋值或者复制赋值
42 = 10;//很明显会报错
可以初始化const左值引用 ,这就是我开头程序报错的原因!我的程序没有
constclass MyClass {
int data;
public:
MyClass(int const& e):data(e){}; //这里的形参引用用const修饰就可以编译通过了!!!
}; int main(){
MyClass c(10);
return 0;
}
可以初始化右值引用;因为右值引用已经超出我的知识范畴了,以后学到再来补充。
为什么右值可以初始化const左值引用
note:下边的引用都是说左值引用
我先来说一下为什么右值不可以初始化普通引用,引用实际上是对指针的封装,主要作用是修改这个指针指向的值,那根据右值的性质:不能被取地址,所以引用和右值绑定显然是非法的。
那为什么加上const就可以了呢?
这是因为将const引用绑定到右值时,编译器采取了一种妥协机制:编译器会为临时数据创建一个新的、无名的临时变量,并将临时数据放入该临时变量中,然后再将引用绑定到该临时变量。注意,临时变量也是变量,所有的变量都会被分配内存。所以说const引用实际上是和右值的一个copy绑定了。
参考:https://zh.cppreference.com/w/cpp/language/value_category#cite_note-3
http://c.biancheng.net/view/vip_2254.html
C++ lvalue(左值)和rvalue(右值)的更多相关文章
- 话说C++中的左值、纯右值、将亡值
写在前面 C++中有“左值”.“右值”的概念,C++11以后,又有了“左值”.“纯右值”.“将亡值”的概念.关于这些概念,许多资料上都有介绍,本文在拾人牙慧的基础上又加入了一些自己的一些理解,同时提出 ...
- C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward
这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...
- c++11 左值引用、右值引用
c++11 左值引用.右值引用 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #i ...
- 左值与右值,左值引用与右值引用(C++11)
右值引用是解决语义支持提出的 这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运 ...
- C++的左值,右值,左值引用,右值引用
参考大神链接: https://blog.csdn.net/u012198575/article/details/83142419 1.左值与右值 https://msdn.microsoft.com ...
- C++左值引用与右值引用
本文翻译自:https://docs.microsoft.com/en-us/cpp/cpp/references-cpp?view=vs-2019 引用,类似于指针,用于存储一个位于内存某处的对象的 ...
- 翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?
本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...
- c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用
为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...
- 深入学习c++--左值引用和右值引用
#include <iostream> #include <string> #include <vector> using namespace std; int m ...
- C++11的左值引用与右值引用总结
概念 在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容):当对象被用作左值的时候,用的是对象的身份(在内存中的位置).左值有持久的状态,而右值要 ...
随机推荐
- k8s系列---资源指标API及自定义指标API
不得不说千万不要随意更改版本,我用的1.13的版本,然后学到这一步时,还因yaml文件不同,卡住了很久,然后各种google才找到解决办法 https://www.linuxea.com/2112. ...
- JMeter接口测试-提取动态列表最后一个值的两种方法
前言 在用JMeter做接口测试时,我们经常会遇到,一个接口返回一个json串,在这个json串中,某个节点的值是一个列表,而且这个列表的长度是动态变化的.今天我们来学习两种提取动态列表最后一个值的两 ...
- 2020-2-27今日总结——滚动监听&导航
利用Bootstrap 开发工具实现滚动监听 (此文只做学习路上的归纳分享总结用,如有侵权,请联系我删除) 使用滚动监听,比较特殊,要在body中设置scroll,以及触点. 很好理解,因为滚动是多对 ...
- RabbitMQ配置死信队列
死信队列 消息传输过程中难免会产生一些无法及时处理的消息,这些暂时无法处理的消息有时候也是需要被保留下来的,于是这些无法被及时处理的消息就变成了死信. 既然需要保留这些死信,那么就需要一个容器来存储它 ...
- vscode自己常用的快捷键
(1)快速复制一行 ctrl + alt +
- 07.JS对象-2
前言: 学习一门编程语言的基本步骤(01)了解背景知识(02)搭建开发环境(03)语法规范(04)常量和变量(05)数据类型(06)数据类型转换(07)运算符(08)逻辑结构(09)函数(10)对象1 ...
- redis中hash数据类型
remoteSelf:1>hset website google "www.google.com" "1" remoteSelf:1>hget we ...
- PHPJN0001:phpmyadmin 允许密码为空 设置
phpmyadmin连接mysql数据库,出于安全考虑,默认不允许使用空密码连接数据库.因为数据库一般都设置密码访问. 但如果只是本机环境测试使用,每隔一段时间都需要填写密码,不是很方便. 如果没有修 ...
- 【python基础语法】常用内置函数、关键字、方法和之间的区别(小结)
''' 关键字: False:bool数据类型 True:bool数据类型 None:表示数据的内容为空 and:逻辑运算符:与 or:逻辑运算符:或 not:逻辑运算符:非 in:身份运算符,判断变 ...
- 安装PHP到CentOS(YUM)
运行环境 系统版本:CentOS Linux release 7.3.1611 软件版本:PHP-7.2 硬件要求:无 安装过程 1.配置YUM源 [root@localhost ~]# rpm -i ...