c++ 左值和右值以及左值引用和右值引用

  • 无法令引用重新绑定到另一个对象上,因此引用必须初始化,引用并非对象,只是为一个已经存在的对象所起的另外一个名字
  • 因为引用本身不是一个对象,所以不能定义引用的引用
int a = 10;
int &b = a;
int &c = b;//此时c不是引用的引用,而是b c 都是a的引用
  • 判断某个表达式是左值还是右值的方法

    • 可以位于赋值号左侧的表达式就是左值;只能位于赋值号右侧的表达式就是右值
    • 有名称的,可以获取到存储地址的表达式为左值,反之为右值
  • 右值引用只能绑定到一个将要销毁的对象,必须进行初始化,只能使用右值来初始化

  • 一般一个左值表达式表示的是一个对象的身份,一个右值表达式表示的是对象的值

int i = 42;
int &r = i;//正确
//    int &&r = i;//错误,不能将一个右值引用绑定到一个左值上
//    int &r2 = i * 42; //错误,i * 42是一个右值
const int &r3 = i * 42; //正确,可以将一个const的引用绑定到一个右值上
int &&r2 = i * 42;//正确

右值引用的使用

  • 和声明左值引用一样,右值引用也必须立即进行初始化操作,而且只能使用右值进行初始化
int &&a = 10;
  • 右值引用可以修改右值
int &&a = 10;
cout<<a<<" "<<&a<<endl;
a = 11;
cout<<a<<" "<<&a<<endl;
  • 存在常量右值引用,但是这种表示没有任何实际用处
    • 右值引用主要用于移动语义和完美转发,前者需要有修改右值的权限
    • 常量右值引用就是引用一个不可修改的右值,可以交给常量左值引用
  • 返回非引用类型的函数,连同算数、关系、位以及后置递增/递减运算符,都生成右值,不能将一个左值引用绑定到这类表达式上,但可以将一个const左值引用或者一个右值引用绑定到这类表达式上
  • 由于右值引用只能绑定到临时对象,可以得知
    • 所引用的对象将要被销毁
    • 该对象没有其他用户
    • 意味着右值引用的代码可以自由地接管所引用的对象的资源

总结

  • 非常量左值引用只可以引用非常量左值,常量左值引用可以引用非常量左值、常量左值以及右值
  • 右值引用不支持引用左值;非常量右值只可以引用非常量右值;常量右值可以引用非常量右值和常量右值
posted @ 2023-06-03 21:07  白菜茄子  阅读(9)  评论(0编辑  收藏  举报