欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++11:右值引用

程序员文章站 2022-03-22 21:38:10
...

左值、右值,和右值引用

左值(lvalue)右值(rvalue)是编译器和程序中常出现的词汇,一个最为典型的判别左值右值的方法是,在赋值表达式中,出现在等号左边的就是左值,出现在等号右边的就是右值。例如
a = b + c;
在这个表达式中,a就是左值,b+c就是右值。
不过 C++中还有另一种被广泛认同的说法:可以取地址的、有名字的就是左值;不能取地址的、没有名字的就是右值。
上述表达式a = b + c;中,a是可以取地址的,即&a,但如果对(b+c)取地址&(b+c)则无法通过编译。因此a是左值,(b+c)是右值。

C++11中右值的判定

C++11中,右值由两个概念构成一个是将亡值,一个是纯右值。

纯右值

纯右值,是用于辨识临时变量和一些不跟对象关联的值。比如
1. 非引用返回的函数返回的临时变量(A getA( ){ })
2. 运算表达式(1+3产生的临时变量)
3. 不跟对象关联的字面量值(1,’a’,true等)
4. 类型转换函数的返回值
5. lambda表达式

将亡值

将亡值,是C++11新增的跟右值引用相关的表达式,这样表达式通常是将要被移动的对象,比如:
1. 返回右值引用T&&的函数的返回值
2. std::move()的返回值
3. 转换为T&&的类型转换函数的返回值。
剩余的,可以标识函数、对象的值都属于左值。
在C++11中,所有的值都必然属于左值、将亡值和纯右值之一。

右值引用

C++11中,右值引用就是对一个右值进行引用的类型。因为右值通常是匿名变量,所以只能通过右值引用来找到它。通常情况下,只能通过右值表达式&&获得其引用。

//假设GetRValue()返回一个右值
class Foo;
Foo GetRValue(){
    return Foo();
}
Foo && a = GetRValue();
Foo b = GetRValue();

对于上面两行代码,第一行是右值引用,第二行是赋值。
对于GetRValue(),在函数内部建立了一个Foo临时对象。当使用右值引用时,a会直接绑定函数返回的临时变量。本来应该在函数结束时释放的临时变量此时将与a的生命周期相同。当简单的运用赋值操作时,将会重新分配一块内存和b绑定,再调用一次Foo的构造函数复制临时变量的内容,最后再释放临时 变量的内存。这样会多一次构造和析构的过程。
值得一提的是,无论是左值引用还是右值引用,都要在声明之后立即进行初始化操作。左值引用是具名变量值的别名,右值引用是不具名(匿名)变量的别名。
这里区分一下:

引用类型 语法
左值引用 T & lref
右值引用 T && rref
相关标签: 右值