前言

对于C++左值引用右值引用的介绍不是很了解,找了几篇文章,然后简单的记录一下。

这里只是记录大概,暂时不深入,想深入看的请看参考文吧。

正文

下面主要介绍左值右值,左值引用和右值引用相关知识。

左值和右值

左值

左值是一个表示数据的表达式,比如:变量名、解引用的指针变量。

总体而言,可以取地址的对象就是左值!

int a = 5;
int *p = &a;
const int b = 2;

a,p和b都是左值。

右值

右值也是一个表示数据的表达式,比如:字面常量、表达式返回值,传值返回函数的返回值(是传值返回,而非传引用返回),右值不能出现在赋值符号的左边且不能取地址。

总体而言,不可以取地址的对象就是右值,也不可以修改右值!

10;                 // 字面常量
x + y;             // 表达式返回值
myAdd(x, y);        // 传值返回函数的返回值

上面10,x+y,myAdd(x,y)都是右值。

右值放在=左边就会报错提示,提示[表达式必须是可修改的左值];对其取地址也会报错,提示[表达式必须为左值或函数指示符]。

总结
  1. 可位于赋值号(=)左侧的表达式就是左值;反之,只能位于赋值号右侧的表达式就是右值。

    左值一般是我们自己定义的编译,在定义时开辟了内存,我们可以对这块内存赋值,也可以修改内存中的值。

    C++中的左值也可以当作右值使用。

    int a = 5;  // a是一个左值
    int b = 10; // b 是一个左值
    a = b; // a、b 都是左值,只不过将 b 可以当做右值使用
  2. 有名称的、且可以获取到存储地址的表达式即为左值;反之则是右值。

    上面变量 a、b 是变量名且通过 &a 和 &b 可以获得他们的存储地址,因此 a 和 b 都是左值;反之,字面量 5、10,它们既没有名称,也无法获取其存储地址(字面量通常存储在寄存器中,或者和代码存储在一起),因此 5、10 都是右值。

  3. 右值的生命周期一般只在当前语句。

    右值一般为临时变量,是程序运行时产生的中间产物,他不是我们用户自己定义开辟空间的,是由编译器帮我们开辟空间,并且在用完就立即销毁。

当然,最简单的判断左值或右值,就看他是否可以取地址。

左值引用 和右值引用

左值引用

左值引用就是给左值的引用,给左值(对象)取别名。

“&”表示的引用又称为左值引用

作用是避免对象拷贝。

int c = 0;
const int b = 2;
int* p = nullptr;
 
//左值引用
int& lc = c;
const int& lb = b;
int*& lp = p;
右值引用

右值引用就是给右值的引用,给右值(对象)取别名。

C++11 标准新引入了另一种引用方式,称为右值引用,用 “&&” 表示。

作用是把延长对象的生命周期,一般是延长到作用域的scope之外

int fun(){
    return 1;
}
void test(){
    int a = 1, b = 2;
 
    //右值引用
    int && r1 = 10;
    int && r2 = (a + b);
    int && r3 = fun();
}
总结
  1. 非常量左值引用可以引用的值的类型只有非常量左值,常量左值引用非常量左值、常量左值及右值

    int num = 10;
    int& a = num;   //编译成功,非常量左值引用支持引用非常量左值
    const int num2 = 100;
    int& b = num2;  //编译失败,非常量左值引用不支持引用常量左值
    int& c = 10;    //编译失败,非常量左值引用不支持引用右值
    
    const int& d = num;     //编译成功,常量左值引用支持引用非常量左值
    const int& e = num2;    //编译成功,常量左值引用支持引用常量左值
    const int& f = 100;     //编译成功,常量左值引用支持引用右值

  2. 右值引用不支持引用左值;非常量右值引用可以引用的值的类型只有非常量右值,常量右值引用非常量右值、常量右值

    int num = 10;
    const int num2 = 100;
    int&& a = num;          //编译失败,非常量右值引用不支持引用非常量左值
    int&& b = num2;         //编译失败,非常量右值引用不支持引用常量左值
    int&& c =10;            //编译成功,非常量右值引用支持引用非常量右值
    const int&& d = num;    //编译失败,常量右值引用不支持引用非常量左值
    const int&& e = num2;   //编译失败,常量右值引用不支持引用常量左值
    const int&& f = 100;    //编译成功,常量右值引用支持引用右值

参考文章

  1. 详解 C++ 左值、右值、左值引用以及右值引用

  2. 【C++】左值和右值、左值引用(&)和右值引用(&&)

  3. C++ 左值引用与右值引用超详解

相关文章

暂无评论

none
暂无评论...