Skip to content

Latest commit

 

History

History
61 lines (49 loc) · 2.66 KB

左值&右值&左值引用&右值引用.md

File metadata and controls

61 lines (49 loc) · 2.66 KB

左值&右值&左值引用&右值引用

c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能。

左值、右值

  • C++中所有的值都必然属于左值、右值二者之一。

  • 左值是指表达式结束后依然存在的持久化对象,右值是指表达式结束时就不再存在的临时对象。

  • 所有的具名变量或者对象都是左值,而右值不具名

  • 区分左值和右值的便捷方法:看能不能对表达式取地址,如果能,则为左值,否则为右值

  • 书上将右值分为将亡值和纯右值。纯右值就是c++98标准中右值的概念,如非引用返回的函数返回的临时变量值;一些运算表达式,如1+2产生的临时变量;不跟对象关联的字面量值,如2,'c',true,"hello";这些值都不能够被取地址。

  • 而将亡值则是c++11新增的和右值引用相关的表达式,这样的表达式通常时将要移动的对象、T&&函数返回值、std::move()函数的返回值等。

  • 不懂将亡值和纯右值的区别其实没关系,统一看作右值即可,不影响使用。

int i=0; // i是左值,0是右值

class A {
  public:
    int a;
};
A getTemp() {
    return A();
}
A a = getTemp();   // a是左值,getTemp()的返回值是右值(临时变量)

左值引用、右值引用

  • c++98中的引用很常见,就是给变量取了个别名。
  • 在c++11中,因为增加了右值引用(rvalue reference)的概念,所以c++98中的引用都称为了左值引用(lvalue reference)。
  • c++11中的右值引用使用的符号是&&。
  • 左值引用, 使用 T&, 只能绑定左值。
  • 右值引用, 使用 T&&, 只能绑定右值。
  • 常量左值引用, 使用 const T&, 既可以绑定左值又可以绑定右值。
  • 已命名的右值引用,编译器会认为是个左值。
int a = 10; 
int &refA = a; // refA是a的别名, 修改refA就是修改a, a是左值,所以是左值引用
// int &b = 1; // 编译错误! 1是右值,不能够使用左值引用
/*****************************************/
int&& a = 1; // a是右值引用,实质上就是将不具名(匿名)变量取了个别名
int b = 1;
// int&& c = b; // 编译错误! 不能使用右值引用绑定左值
class A {
  public:
    int a;
};
A getTemp()
{
    return A();
}
A && a = getTemp(); // a是右值引用,getTemp()的返回值是右值(临时变量),a延长了右值临时变量的生命周期。

参考链接

[c++11]我理解的右值引用、移动语义和完美转发 - 简书 (jianshu.com)