C++ 右值引用和移动语义学习笔记

C++中的右值引用和移动语义能够有效避免无谓的复制,提高程序运行效率。右值引用允许对临时对象进行引用,延长其生命周期,而移动构造函数利用右值引用实现资源的浅拷贝,减少深拷贝的开销。std::move()函数可将左值转换为右值引用,启用移动语义。通过理解和运用这些概念,开发者可以优化含有大量资源的对象处理,提升C++程序的性能。
摘要由CSDN通过智能技术生成

C++中使用右值引用和移动语义,可以避免无谓的复制,提高程序性能。

左值是表达式结束后仍然存在的持久对象,右值是表达式结束后就不存在的临时对象。

  • 区分左值和右值的的便捷方法就是看能不能对表达式取地址,如果能则为左值,否则为右值;
  • 将亡值是C++新增的、与右值引用相关的表达式,比如:将要被移动的对象、T&&函数返回的值、std::move返回值和转换成T&&的类型的转换函数返回值;
  • C++中的所有值必将属于左值、将亡值、纯右值三者之一,将亡值和纯右值都属于右值。

左值lvalue是有标识符、可以取地址的表达式,最常见的有:

  • 变量、函数或数据成员的名字
  • 返回左值引用的表达式,如++x、x=1、cout<<""
  • 字符串字面量如“hello world”

纯右值prvalue是没有标识符、不可取地址的表达式,一般称之为临时对象。最常见的情况有:

  • 返回非引用类型的表达式,如x++、x+1、make_shared(42)
  • 出字符串字面量之外的字面量,如42、true等

&&的特性

右值引用就是对一个右值进行引用的类型。无论声明左值引用还是右值引用都必须立即进行初始化,因为引用类型本身并不拥有所绑定对象的内存,只是该对象的一个别名。

通过右值引用的声明,该右值又“重获新生”,其生命周期与右值引用类型变量的生命周期一样,只要该变量还活着,该右值临时变量将会一直存活下去。

&&的总结如下:

  • 左值和右值是独立于它们的类型的,右值引用类型可能是左值也可能是右值。
  •  auto&& 或函数参数类型自动推导的 T&& 是一个未定的引用类型,被称为 universal references,它可能是左值引用也可能是右值引用类型,取决于初始化的值类型。
  • 所有的右值引用叠加到右值引用上仍然是一个右值引用,其他引用折叠都为左值引 用。当 T&& 为模板参数时,输入左值,它会变成左值引用,而输入右值时则变为具名的右 值引用。
  • 编译器会将已命名的右值引用视为左值,而将未命名的右值引用视为右值。

右值引用优化性能,避免深拷贝

对于含有堆内存的类,我们需要提供深拷贝的拷贝构造函数,如果使用默认构造函数,会导致堆内存的重复删除。

使用临时变量拷贝构造新的对象时 ,临时变量在拷贝构造完成之后就销毁了。如果堆内存很大,那么,这个拷贝构造的代价会很大,带来了额外的性能损耗。有没有办法避免临时对象的拷贝构造呢?答案是肯定的。我们可以使用移动构造。

移动构造函数只是将临时对象的资源做了浅拷贝,不需要对其进行深拷贝,从而避免了额外的拷贝,提高性能。这也就是所谓的移动语义( move 语义),右值引用的一个重要目的是用来支持移动语义的。

移动语义可以将资源(堆、系统对象等)通过浅拷贝方式从一个对象转移到另一个对象,这样能够减少不必要的临时对象的创建、拷贝以及销毁,可以大幅度提高 C++ 应用程序的性能,消除临时对象的维护(创建和销毁)对性能的影响。

移动语义

我们知道移动语义是通过右值引用来匹配临时值的,那么,普通的左值是否也能借组移动语义来优化性能呢?C++11为了解决这个问题,提供了std::move()方法来将左值转换为右值,从而方便应用移动语义。move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转义,没有内存拷贝。

在现有的 C++ 机制中,我们可以定义拷贝构造函数和赋值函数。要实现转移语义,需要定义转移构造函数,还可以定义转移赋值操作符。对于右值的拷贝和赋值会调用转移构造函数和转移赋值操作符。如果转移构造函数和转移拷贝操作符没有定义,那么就遵循现有的机制,拷贝构造函数和赋值操作符会被调用。

参考资料

<<零声教育--C++进阶重点知识精讲1>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值