c++右值引用

右值引用

1.左值和右值

​ 左值:指一个指向特定内存的具有名称的值,它有一个相对稳定的地址并有一段较长的声明周期

​ 右值:不指向稳定内存地址的匿名值,它的生命周期很短。(如函数返回时构建的临时对象)

常见的左值和右值

​ 前置++:前置++的实现是将对象自增,然后返回这个对象本身,所以前置++的返回是左值。

​ 后置++:后置++的实现创建一个临时对象,在对传入对象自增,最后返回临时对象,所以后置++返回右值。

​ 字符串字面量(常量):字符串字面量是左值。因为编译器会将它存储到数据段中,程序加载的时候会为它开辟固定的内 存。

2.右值引用

​ 顾名思义,右值引用是一种引用右值切只能应用于右值的方法。它可以延长临时对象的声明周期,目的是减少对象的复制,避免不必要的拷贝,提升性能。它的主要意义是支持移动语义完美转发

​ 注:常量左值引用能引用右值。

​ 例:1.用右值引用接受函数的返回值,这样函数直接将return时产生的临时对象返回给右值引用,避免了一次拷贝构造函数的执 行。

​ 2.在使用一个临时对象创建一个对象时,我们可以使用移动构造函数。这时,资源将从一个临时对象(右值)“移动”到新对 象,而不是创建新资源的拷贝。减少了不必要的拷贝操作。

RVO介绍

​ RVO是一种编译器优化技术,用于消除不必要的临时对象拷贝,从而提高性能。它主要针对函数返回局部对象的情况,通过 优化,可以避免创建临时对象并执行拷贝构造函数。

​ RVO的思想:在函数调用栈上直接构造返回值,而不是先创建一个局部对象,再拷贝到调用者的栈空间。

3.移动语义

​ 移动语义帮助我们将临时对象的内存转移到另一个对象中,来避免内存数据的复制。原理是在类中创建一个移动构造函数,它以右值引用作为形参,函数中不进行资源的拷贝,而是进行资源所有权的转让。对于右值,编译器会优先使用移动构造函数去构造目标对象。

4.将亡值和std::move()

​ 将亡值表示资源可以被重用的对象和位域,通常这是因为它们接近生命周期的末尾,也坑你是经过右值引用的转换产生的。

​ 将左值转换成右值引用代码

1
static_cast<classname&&>(xxxx)

​ 这个操作的意义是让左值使用移动语义,std::move()实质上与上述代码等价。