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绑定”,里边有两个关键词:lvaluervalue

什么是lvalue(左值)

简单定义:内存中有确定存储地址的对象的表达式的值,可以是一个变量名:int a;,可以是一个赋值表达式a=b,或者字符串常量"cnblogs",总之,最简单鉴别的方法就是编译以下这个句子&(需要鉴别的表达式),能通过编译就是左值。

严格定义见:C++文档

左值有什么性质?

  1. 可以被取地址(&),上边我们就是用这个方法来鉴别左值。

  2. 可以被赋值,或者复制赋值;

    //赋值
    int a = 10;
    //复制赋值
    int a(10);
  3. 可以初始化左值引用,也就是我们常用的引用;

    int a=10;
    int& reference = a;

    这是一些常用的性质,更多性质见:C++文档

什么是rvalue(右值)

:非左值。

常见的有字面值(除了字符串常量),后置自增自减表达式a++;a--;

右值有什么性质?

  1. 不能被取地址

    int a = 1;
    int* p = &(a++); //报错,a++是右值,不能被取地址,而++a是左值
  2. 不能被赋值或者复制赋值

    42 = 10;//很明显会报错
  3. 可以初始化const左值引用 ,这就是我开头程序报错的原因!我的程序没有const

    class MyClass {
    int data;
    public:
    MyClass(int const& e):data(e){}; //这里的形参引用用const修饰就可以编译通过了!!!
    }; int main(){
    MyClass c(10);
    return 0;
    }
  4. 可以初始化右值引用;因为右值引用已经超出我的知识范畴了,以后学到再来补充。

为什么右值可以初始化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(右值)的更多相关文章

  1. 话说C++中的左值、纯右值、将亡值

    写在前面 C++中有“左值”.“右值”的概念,C++11以后,又有了“左值”.“纯右值”.“将亡值”的概念.关于这些概念,许多资料上都有介绍,本文在拾人牙慧的基础上又加入了一些自己的一些理解,同时提出 ...

  2. C++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

    这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运行测试过的,希望能用这些帮助理 ...

  3. c++11 左值引用、右值引用

    c++11 左值引用.右值引用 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #i ...

  4. 左值与右值,左值引用与右值引用(C++11)

    右值引用是解决语义支持提出的 这篇文章要介绍的内容和标题一致,关于C++ 11中的这几个特性网上介绍的文章很多,看了一些之后想把几个比较关键的点总结记录一下,文章比较长.给出了很多代码示例,都是编译运 ...

  5. C++的左值,右值,左值引用,右值引用

    参考大神链接: https://blog.csdn.net/u012198575/article/details/83142419 1.左值与右值 https://msdn.microsoft.com ...

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

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

  7. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part5:右值引用就是右值吗?

    本文为第五部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/cpp-rvalue-references-explained-introduction.ht ...

  8. c++ 11 移动语义、std::move 左值、右值、将亡值、纯右值、右值引用

    为什么要用移动语义 先看看下面的代码 // rvalue_reference.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #includ ...

  9. 深入学习c++--左值引用和右值引用

    #include <iostream> #include <string> #include <vector> using namespace std; int m ...

  10. C++11的左值引用与右值引用总结

    概念 在C++11中,区别表达式是左值或右值可以做这样的总结:当一个对象被用作右值的时候,用的是对象的值(内容):当对象被用作左值的时候,用的是对象的身份(在内存中的位置).左值有持久的状态,而右值要 ...

随机推荐

  1. zabbix-proxy配置文件参数说明

    配置文件路径: /etc/zabbix/zabbix_proxy.conf Server=10.0.0.10 #<===指定zabbix server的ip地址或主机名 Hostname=zab ...

  2. ASP.NET Core ResponseCache进行缓存操作

    前言 本章将介绍客户端缓存将介绍浏览器缓存和服务端缓存,使用浏览器缓存将减少对web服务器的请求次数,同时可以提升性能,避免重复的运算浪费. ASP.NET Core对于HTTP缓存分为两种: 客户端 ...

  3. js垃圾回收与内存泄漏

    js垃圾回收机制 概念: javascript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中的使用的内存.而在C和C++之类的语言中,开发人员的一项基本任务就是手动跟踪内存的使用情况 ...

  4. printf函数中*修饰符的作用,如:%*d

    在printf函数中,我们可以用数字修饰来控制打印的字段宽度和精度,如下(为强调视觉效果,均填充0): #include <stdio.h> int main() { ; float f= ...

  5. iis添加asp.net网站,访问提示:由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射

    今天在iis服务器配置asp.net网站,遇到一个问题,记录一下: 问题:由于扩展配置问题而无法提供您请求的页面.如果该页面是脚本,请添加处理程序.如果应下载文件,请添加 MIME 映射. Windo ...

  6. git基础教程(三)

    3.github与git同步 3.1 配置公私钥 3.2 github上建立个人仓库 3.3 本地仓库同步到github #将本地仓库与远端仓库建立连接 #用简写名代替后面的远端连接 git remo ...

  7. STM32之RGB灯仿真

    实验目的 点灯是练习GPIO输出的最佳实验.由于疫情期间没法返校,手头上没有现成的实验板,于是借助Proteus进行仿真.本实验点的不是普通的灯,而是RGB混色灯,实现多种颜色的显示.后期还可以加上P ...

  8. opencv —— HoughLines、HoughLinesP 霍夫线变换原理(标准霍夫线变换、多尺度霍夫线变换、累积概率霍夫线变换)及直线检测

    霍夫线变换的原理 一条直线在图像二维空间可由两个变量表示,有以下两种情况: ① 在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示. ② 在极坐标系中:可由参数极经和极角(r,θ)表示. 对于霍夫线变 ...

  9. java如何解决线程安全问题

    方式一:同步代码块 synchroized(同步监视器的对象){需要被同步的代码} package threadtest; //使用同步代码块实现Runable接口的线程 public class R ...

  10. 面试官:Java序列化为什么要实现Serializable接口?我懵了

    整理了一些Java方面的架构.面试资料(微服务.集群.分布式.中间件等),有需要的小伙伴可以关注公众号[程序员内点事],无套路自行领取 更多优选 一口气说出 9种 分布式ID生成方式,面试官有点懵了 ...