左值引用与右值引用的区别?右值引用的意义?

左值引用与右值引用的区别?右值引用的意义?

  • 1 区别
    • 1.1 功能差异
      • 1.2 左值引用
      • 1.3 右值引用
        • 1.3.1 实现移动语义
        • 1.3.2 实现完美转发
  • 2 引用的作用
  • 3 区分左值和右值
    • 3.1 左值
    • 3.2 右值

1 区别

左值引用是对左值的引用;右值引用是对右值的引用。

(1)使左值指向右值

const 左值引用能指向右值,局限是不能修改这个值。

注意:使用const不能修改值时,可以使用引用,引用该值并对其进行修改。

(2)使右值指向左值

右值引用通过**std::move(v)**可以将左值转化为右值,此时右值就是将亡值。

(3)声明出来的左值引用或右值引用都是左值

int i=0;

//引用是必须初始化
//此时的j引用的是右值'100'
int && j=100; //右值引用  

int & k=i;//左值引用

1.1 功能差异

1.2 左值引用

避免对象拷贝。

  • 函数传参
  • 函数返回值

1.3 右值引用

1.3.1 实现移动语义

解决对象赋值的问题,避免资源(堆上)的重新分配。有深拷贝的情况下。

以数据库举例。

以前:与数据库创建连接,不想把连接对象关闭,需要再创建另一个连接,再把连接资源拿过来。

现在:直接把连接对象的资源拿给另一个对象是用,就不用再创建并删除一个与数据库之间的连接对象。

以文件举例。

以前:一个文件描述fd,按照以前的深拷贝需要重新打开一个文件。

现在:直接把该文件资源fd移动到另外一个对象中就可以了。

拷贝赋值构造与拷贝构造:

//拷贝赋值构造 深拷贝(资源的重新分配)
A a1,b1;
a1=b1; 

//拷贝构造 深拷贝
A a2;
A b2(a2);//当前a2是左值
cout<<"b,p="<//深拷贝
A(const A&a)//拷贝构造
{
    //拷贝构造中使用的是const,只能读,不能写,所以不能再拷贝构造中使用移动构造进行资源转移
	p=new int(10);
    memcpy(p,a.p,10*sizeof(int));//重新分配内存
    cout<<"A(const A&):p="<p=a.p;
    a.p=nullptr;
    cout<<"A(A&&)"<

stl中的应用:

list alist;
alist.push_back(A());//当前A()为右值
auto &ele=alist.front();//取出第一个值
cout<<"ele.p="<

1.3.2 实现完美转发

定义:函数模板可以将自己的参数完美地转发给内部调用的其他函数。

完美指的是不仅能准确地转发参数的值,还能保证转发的参数的左右值属性不变。使用std::forward(v)实现。

//左值
void func(int &n)
{
    cout<<"left value="<template
void  tempFun(T&& t) {}  //模板类型的这种用法 T && 是万能引用最常见的使用场合

2)具有模板推导:

auto&& var2 = var1;  //auto这种需要推断类型的地方

万能引用虽然跟右值引用的形式一样,但右值引用需要是确定的类型,如: int && ref = x;就是右值引用。

借用万能引用的方式接受左右属性的值。使用引用折叠规则实现。

template