• C++ 左值、右值、左值引用以及右值引用


    一、左值和右值 将亡值

    1.左值

    左值是一个表示数据的表达式,比如:变量名、解引用的指针变量。一般地,我们可以获取它的地址对它赋值,但被 const 修饰后的左值(常性),不能给它赋值,但是仍然可以取它的地址。

    总体而言,凡是能够取地址的值叫做左值。

    1. int a = 10; //&a
    2. int* ip = &a; //&ip
    3. const int b = 20; //&b
    4. const int* bp = &b; //&bp

    2.右值

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

    总体而言,不能够取地址的值叫做右值。

    1. &10;
    2. &12.23 右值
    3. &NULL;
    1. &10;&12.23;&NULL;,VS2019 编译报错: “&” 要求左值。原因:右值不能取地址。

    3.将亡值 

     将亡值是表达式或函数调用时产生的一个临时量,凡是由内置类型产生的将亡值,它都是一个字面量(只可读不可写),不能够被修改

    1. int main()
    2. {
    3. int a = 10, b = 20;
    4. int c = 0;
    5. c = a + b;//计算值存在 计算结束没了 将亡值
    6. }

     

    1. int Add(int a, int b)
    2. {
    3. int c = a + b;
    4. return c;
    5. }
    6. int main()
    7. {
    8. int x = 0;
    9. x = Add(12, 23);
    10. }

     

    二、左值引用和右值引用 

    C++ 语法中就存在引用语法,而 C++11标准中新增了右值引用的语法特性,因此为了区分两者,将C++11标准出现之前的引用称为左值引用。

    无论左值引用还是右值引用,都是给对象取别名。

    1.左值引用

    左值引用就是对左值的引用,给左值取别名

    1. int a = 10;
    2. const int b = 20;
    3. int& ra = a; //普通引用
    4. const int& rca = a; //常性引用
    5. const int& rb = b; //常性引用

    2.右值引用

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

    1. //int& rr = 10;
    2. int&& rr = 10; //int && right 右值引用

    右值引用引用右值,会使右值被存储到特定的位置。
    也就是说,右值引用变量其实是左值,可以对它取地址和赋值(const右值引用变量可以取地址但不可以赋值,因为 const 在起作用)。
    当然,取地址是指取变量空间的地址(右值是不能取地址的)。 

    3.对比与总结

    左值引用总结:

    1. 左值引用只能引用左值,不能直接引用右值。
    2. 但是const左值引用既可以引用左值,也可以引用右值。
    1. int main()
    2. {
    3. int a = 10;
    4. int& ra = a;
    5. const int& rca = a;
    6. //int&& rr = a; //a是一个左值 右值引用不匹配
    7. int&& rr = 20;
    8. }
    1. int main()
    2. {
    3. const int& ra = 10; //万能引用(不管是左值还是右值都能引用)
    4. //int tmp=10;
    5. //const int& ra =tmp;
    6. //ra += 100; err
    7. int&& rr = 10; //右值引用
    8. //int tmp=10;
    9. //int &rr=tmp;
    10. rr += 100;
    11. int& a = rr;
    12. //把右值固定到rr上 rr是一个右值引用,
    13. //右值引用有名字,可以对右值引用取地址(右2名字就能取地址)
    14. //右值一旦具有名字就变成左值
    15. //int&& a = rr; err
    16. }

    右值引用总结:

    1. 右值引用只能引用右值,不能直接引用左值。
    2. 但是右值引用可以引用被move的左值。

    三、示例

    代码如下:

    1. //C++ a: //类型 值类别 left right xval;
    2. //void func(int a) { cout << "func(int)" << endl;} //传值
    3. void func(int &b) { cout << "func(int &)left ref" << endl; } //左值引用(可以取地址)
    4. void func(const int&c) { cout << "func(const int &c const left ref)" << endl; } // 万能引用 //常引用
    5. void func(int&& d) { cout << "func(int &&)right ref)" << endl; } //右值引用(不能取地址)
    6. int main()
    7. {
    8. func(10); //int &&d =>const int &c;
    9. return 0;
    10. }
    11. int main()
    12. {
    13. const int x = 10; //常性
    14. func(x); //(const int &b)
    15. return 0;
    16. }
    17. int main()
    18. {
    19. int x = 10;
    20. func(x); //产生二义性 //int &b => (const int &b)
    21. return 0;
    22. }
    23. int add(int a, int b)
    24. {
    25. int c = a + b;
    26. return c;
    27. }//tmp=c;//将亡值 存在于表达式的临时量
    28. int main()
    29. {
    30. int a = 10, b = 20;
    31. int x = add(a, b);
    32. return 0;
    33. }

  • 相关阅读:
    Python二分查找
    每天五分钟机器学习:数据和特征决定机器学习的上限(特征工程)
    mac: docker安装及其Command not found: docker
    linux常用命令
    一个例子形象的理解协程和线程的区别
    2023网安面试题170道,轻松应对面试
    DAO 与存储库Repository模式
    智慧城市中的公共服务创新:让城市生活更便捷
    MySQL数据库
    A-Level数学例题解析及练习Natural logarithms
  • 原文地址:https://blog.csdn.net/hmh520i/article/details/131007665