0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是左值、右值呢?左右值和左右值引用

冬至子 来源:iDoitnow 作者:艰默 2023-07-18 15:39 次阅读

1. 左右值和左右值引用

什么是左值、右值呢? 一种极不严谨的理解为:在赋值的时候,能够被放到等号左边的值为左值,放在右边的值为右值。例如:

int sum(int x, int y){return x + y;}

int a = 1;        //a为左值,常数1为右值
int b = a + a;    //b为左值,表达式a+a为右值
int c = sum(a, a);//c为左值,但函数sum(a, a)返回值为右值

通过上面的例子,常数a、表达式(a+a)和函数sum(a+a)返回值他们都是临时值,这些值都保存在寄存器中,无法取到他们的地址;而对于abc为具体的变量名,存储在内存中,可以取到其地址。因此一般情况下可以根据能否取到地址,来区分左值和右值。

在了解左值和右值之前,我们首先要知道表达式的概念: 由运算符和运算对象构成的计算式(类似数学中的算术表达式) 。表达式是可以求值的,因此根据表达式值的类别,可以对其进行分类(准确的来说,是表达式的结果的值类别,但我们一般不刻意区分表达式和表达式的求值结果,所以这里称“表达式的值类别”。),C++11之后将表达式定义了五种类型:

  • lvalue (Left-hand-side value,左值)
  • prvalue (Pure rvalue,纯右值)
  • xvalue (eXpiring value,将亡值)
  • rvalue (Right-hand-side value,右值)
  • glvalue (Generalized lvalue,泛左值)

它们之间的关系如下图所示:

图片

C++11中将表达式按值类别可以分为 左值将亡值纯右值 。其中,左值和将亡值合称为泛左值,纯右值和将亡值合称为右值。

随着移动语义(后面我们会详细介绍)引入到 C++11 之中,值类别被重新进行了定义,C++之父Bjarne Stroustrup在《“New” Value Terminology》中给出以区别表达式的两种独立的性质:

  • 拥有身份 (identity):可以确定表达式是否与另一表达式指代同一实体,例如通过比较它们所标识的对象或函数的(直接或间接获得的)地址;
  • 可被移动 :移动构造函数、移动赋值运算符或实现了移动语义的其他函数重载能够绑定于这个表达式。

C++11 中:

  • 拥有身份且不可被移动的表达式被称作 左值 (lvalue)表达式;
  • 拥有身份且可被移动的表达式被称作将****亡值 (xvalue)表达式;
  • 不拥有身份且可被移动的表达式被称作 纯右值 (prvalue)表达式;

1.1 左值

一般情况下,左值我们可以简单地理解理解为: 能够使用&取地址的表达式

常见的左值有:

  • 变量名
  • 函数名
  • 返回左值引用的函数调用
  • 前置自增/减的运算符链接的表达式(如++i/--i
  • 内置的赋值表达式(如a=b,a+=1
  • 字符串等。

:字符串是可以取地址的,因此字符串常量也属于左值】

1.2 纯右值

纯右值:表达式本身就是纯粹的字面值(如1ture1.0);或者,该表达式求值结果相当于一个字面值或一个不具名的临时对象。

常见的纯右值有:

  • 除字符串字面值以外的字面值
  • 返回非引用类型的函数调用
  • 后置自增/减的运算符链接的表达式(如i++/i--
  • 算术/逻辑/比较表达式(如a+ba&&ba==b
  • 取地址表达式(如&a

1.3 将亡值

将亡值是在C++11中引进来的,顾名思义,就即将销毁的东西。将亡值的产生与右值引用的产生而引起的,对于将亡值我们常用到的有:

  • 返回类型是右值引用的函数调用或重载运算符的表达式(如std::move(x)
  • 转换为右值引用的转换函数的调用表达式(如static(a)

1.4 左右值引用

左值引用就是对左值的引用。它的形式如:T&,根据const属性可以分为两种:

  • const左值引用
  • 非const左值引用

例如:

int a = 1;
int& la = a;//la为a的左值引用(非const左值引用)
la = 2;//la为非const左值引用,可以修改它的值

const int& c_la = a;//c_la为a的左值引用(const左值引用)
c_la = 2;//该语法错误,c_la为const左值引用,不可以修改它的值

右值引用就是对右值的引用,通过T&&来表示。右值的引用只能绑定到右值上。

2. 移动语义

在未出现右值引用之前,我们在函数调用传参的时候,在某些时候可以使用按引用传递参数,减少参数多的拷贝对资源的消耗,提高程序的运行效率。当我们在处理包含大量数据的对象时,移动语义显的尤为重要。

2.1 std::move

如何将一个左值转换为一个右值呢?C++11在头文件utility中声明了std::move()函数,该函数的作用就是类型转换,通过它,我们可以 把一个左值,将其标记为右值。move()不做任何资源转移的操作,只是产生一个将亡值表达式来标识参数x,其完全等同于static_cast(x)。例如:

int a = 1;
int&& r_a = a; //错误,右值引用只能绑定到右值上,而a是一个左值
int&& r_a = std::move(b); //正确, std::move(a) 是一个右值,可以用右值引用绑定

2.2 移动构造函数

一个类 T 的首个形参是 T&&、const T&&volatile T&&const volatile T&&,且没有其他形参,或剩余形参都有默认值。

具体的形式如下:

T (T &&) //移动构造函数的典型声明形式
T (T &&) = default; //强制编译器生成移动构造函数。
T (T &&) = delete; //避免隐式生成移动构造函数。

示例:

#include < string >
#include < iostream >
#include < utility >

class A
{
    private:
    std::string s;
    public:
    A(std::string str = "A()") : s(str) {std::cout<

2.3 移动赋值运算符

一个类 T 的移动赋值运算符是名为 operator=的非模板非静态成员函数,它接受恰好一个 T&&const T&&volatile T&&const volatile T&& 类型的形参。

具体的形式如下:

T & T ::operator= (T &&) //移动赋值运算符的典型声明
T & T ::operator= (T &&) = default; //强制编译器生成移动赋值运算符
T & T ::operator= (T &&) = delete; //避免隐式移动赋值

示例:

#include < string >
#include < iostream >
#include < utility >
 
class A
{
    private:
    std::string s;
    public:
    A(std::string str = "A()") : s(str) {std::cout<
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 转换器
    +关注

    关注

    27

    文章

    8696

    浏览量

    147105
  • C++语言
    +关注

    关注

    0

    文章

    147

    浏览量

    6989
收藏 人收藏

    评论

    相关推荐

    什么是有效?有效是什么意思?

    什么是有效?有效是什么意思? 有效----在两个相同的电阻器件中,分别通过直流电和交流电,如果经过同一时间
    发表于 04-17 10:31 1.8w次阅读

    箱体的Q,箱体的Q是什么意思

    箱体的Q,箱体的Q是什么意思 一,Qtc: 音箱全系统的总Q, 二,箱体的损耗Q
    发表于 03-31 13:47 5046次阅读

    光圈/F/4K是什么意思

    光圈/F/4K是什么意思 光圈/F 镜头的透光能力。F是物镜焦距(EFL)与入射光瞳周长(D)的
    发表于 04-10 13:42 2912次阅读

    音箱系统Q

    一,Qtc:  音箱全系统的总Q, 二,箱体的损耗Q: Ql-泄漏损耗Q. 由箱体及单元密封不好造成泄漏产
    发表于 10-24 15:17 1.3w次阅读

    电容的Q和D是什么?Q和D有什么作用?

    选择电感电容时特别关注他们的Q,那什么是Q?Q是什么意思,它为什么重要?
    的头像 发表于 09-13 14:16 7.6w次阅读
    电容的Q<b class='flag-5'>值</b>和D<b class='flag-5'>值</b>是什么?Q<b class='flag-5'>值</b>和D<b class='flag-5'>值</b>有什么作用?

    、传址、传引用的区别,哪个更高效?

    、传址、传引用的区别,哪个更高效?
    的头像 发表于 06-29 15:05 6389次阅读

    基于权和基于夏普利的图像酬劳分配机制

    基于权和基于夏普利的图像酬劳分配机制
    发表于 06-24 15:35 43次下载

    C++基础语法中的引用、封装和多态

    本期是C++基础语法分享的第六节,今天给大家来分享一下: (1)引用; (2)宏; (3)成员初始化列表; (4)封装; (5)继承; (6)多态; 引用
    的头像 发表于 09-12 09:58 1307次阅读

    一文带你了解电容的Q和D

    在做射频的时候,选择电感电容时特别关注他们的Q,那什么是Q?Q是什么意思,它为什么重要? 品质因数Q:表征一个储能器件(如电感线圈、电容等)、谐振电路所储能量同每周损耗能量之比
    发表于 02-11 10:47 5次下载
    一文带你了解电容的Q<b class='flag-5'>值</b>和D<b class='flag-5'>值</b>

    EMI读数是以QP还是PK为准

    EMI读数是以QP还是PK为准 ?
    的头像 发表于 05-08 09:46 7529次阅读
    EMI读数是以QP<b class='flag-5'>值</b>还是PK<b class='flag-5'>值</b>为准

    电容的Q与D

    在做射频的时候,选择电感电容时特别关注他们的Q,那什么是Q?Q是什么意思,它为什么重要?
    的头像 发表于 05-29 16:01 5831次阅读
    电容的Q<b class='flag-5'>值</b>与D<b class='flag-5'>值</b>

    稚晖君刚拿了百度投资 市场估十几亿美元左右

    据报道,华为天才少年稚晖君创业项目智元机器人最近完成了第三轮融资,市场估达到了十几亿美元左右
    的头像 发表于 05-31 16:07 1501次阅读

    通友集团一体成型电感-电感的Q是什么?怎么增加Q

    通友集团一体成型电感-电感的Q是什么?怎么增加Q? 被动元件【电感器】在各类电路中的应用是十分常见的,按照不同的性质、形式或结构,分成多种类型 我们都知道电感Q越高越好,那么,
    的头像 发表于 08-07 21:25 818次阅读
    通友集团一体成型电感-电感的Q<b class='flag-5'>值</b>是什么?怎么增加Q<b class='flag-5'>值</b><b class='flag-5'>呢</b>?

    怎么知道电容的SFR是多少?如何选取不同SFR的电容

    怎么知道电容的SFR是多少?如何选取不同SFR的电容?是选取一个电容还是两个电容? 一、什么是电容的SFR 电容的SFR是指自然电容(也可称为串联电容)与薄膜电容(也可称为平行电容)的比值
    的头像 发表于 10-23 09:52 1770次阅读

    中间继电器的动作与释放可调吗

    中间继电器的动作和释放通常是可以调整的,以满足不同的应用需求。动作是继电器触发动作所需的控制电压或电流,而释放则是继电器解除动作所
    的头像 发表于 02-05 15:09 8553次阅读