[c++] 左值、右值、将亡值

1. 概述

1)c++11以前,有左值和右值概念,c++11以后引入了右值引用,因此产生了纯右值和将亡值的概念。

2)左值、右值、将亡值是指值的“类别”,而左值引用和右值引用是值的“类型”。例如,右值引用也可能是一个“左值”(即由一个左值去引用了一个右值)。

2.表达式和值类别

1)表达式

由运算符和运算对象构成。字面量、变量、函数返回值也算作表达式。

2)值类别

对表达式求值的结果,除了结果的值以外,还需要关注它的两个属性,类型和值类别。

类型即int、bool这种,值类别指左值、将亡值、(纯)右值。

注意:左值引用、右值引用是类型,而非类别。一个右值引用也可以是左值。

3.左值

能够用 & 取地址

包括:

1)函数名、变量名(即函数指针和具名变量,例如std::endl)

2)返回左值引用的函数调用

3)前置自增或自减运算符的表达式(++i --i)

4)赋值运算符和复合赋值运算符连接的表达式(a=b a+=b)

5)解引用表达式(*p)

6)字符串字面量("abc"),这是字面量里的特例

 4.纯右值

纯粹的字面值,例如5;表达式求值结果为一个字面量或者不具名临时对象;

包括:

字符串字面量以外的字面值、返回非引用类型的函数调用、后置自增/自减表达式、算术表达式、逻辑和比较表达式、取地址表达式。

判断:

1)++i为左值,i++为右值

++i是对i加一,得到的还是i(一个具名变量)。i++是先拷贝一个i的副本使用,然后对i加一,这个副本是不具名的。

2)解引用表达式(*p)是左值,取地址表达式(&p)是右值

*p是取得对象,可以被取址,因此为左值。而&p得到的是一个具体的地址值(字面量),因此是右值。

3)逻辑运算符、算术表达式,它们的结果是一个新的临时变量/或字面量(true和false),因此是右值。

5.将亡值

c++11新引入的概念,类似于右值,但一般用于移动赋值,在完成了移动资源的初始化或者赋值任务后,会被马上销毁(析构),因此是将亡值。

将亡值在功能上大体类似于纯右值,即都不能做左操作数、可以使用移动构造和赋值运算符。

包括:

1)返回右值引用的函数调用表达式

2)转换为右值引用的转换函数调用表达式

例如: srd::move(x)、static_cast<X&&>(x)

6.补充

1)字符串的字面量实际上是一个char数组,因此他是可以被取址的,知识被编译器禁止了这种操作。

2)具名的右值引用是左值,而匿名的右值引用是右值。

举例:

void foo(X&& x){
    X nx = x;   
}

  此例子中,x为右值引用,但因为具名,因此被看作左值,nx初始化时调用复制构造函数。接下来x依然可以被用到。

X&& get() {...}

X& foo(X&& x){
    return x;
}

foo(get());

get函数返回一个匿名右值引用。其唯一作用是初始化foo的形参,因此它是右值的意义就是可以在这里移动赋值,避免开销。

posted @ 2022-08-26 14:28  Cheung-10  阅读(169)  评论(0)    收藏  举报