左值引用和右值引用区别
- 概念:左值引用是对左值的引用,右值引用是对右值的引用。下面会介绍什么是左值和右值!
- 功能差异:左值引用的目的是防止函数在进行传参和返回值的时候进行对象拷贝。右值引用是为了移动语义和完美转发。
左值和右值区别
- 左值可有在等号左边,能够取地址,具名。举例:变量名、返回左值引用的函数调用,前置自增或自减、赋值运算或复合赋值运算,解引用。
- 右值只能在等号右边,不能取地址,不具有名字。举例:纯右值,纯右值包含字面值,返回非引用类型的函数调用,后置自增与自减,算数表达式、比较表达式。还有就是将亡值,将亡值是C++11引用的右值引用(移动语义)相关的类型。将亡值用来触发移动构造函数和移动赋值构造函数,进行资源转移,之后将亡值会调用析构函数。
右值引用是不是只能对右值引用?
不是的!想要右值引用引用左值,第一种方法可以将左值前加const,但是这样会有问题,我们希望通过引用可以修改变量值,如果左值前加上const,虽然能够被右值引用,但不能被修改。第二种方法是通过std::move(v)函数,v将可以被右值引用。另外需要注意的是声明出的左值引用和右值引用都是左值。
移动语义的理解
解决因进行对象深拷贝而造成的资源重新分配的问题。
在C++11之前进行我们想要构造一个与A一样的B对象,我们需要重新分配一块内存,把A对象里面的资源拷贝到B里面,然后把A释放掉,这样就得到了一个与A一样的B对象。这是一个深拷贝的过程,将会造成资源的重新分配。而在C++11 之后,通过移动构造和移动拷贝构造可以将A对象迁移为B对象,提高效率。在stl、std::unique智能指针中已经广泛被应用。
完美转发的理解
- 函数模板可以将自己的参数完美转发给内部调用的其他函数;
- 完美是指不仅能准确转发参数的值,还能保住被转发的参数的左右属性不变;
- 借用万能引用,通过引用的方式接收左右属性的值;
- 引入折叠原则,参数为左值或者左值引用,T&& 将转化为int&,参数为右值或者右值引用,T&&将转化为int &&.
- 通过std::forward<T>(v),T为左值引用,v将转化为T类型的左值,T为右值引用,v将转化为T类型右值。