您的位置:首页 > 游戏 > 手游 > 石家庄房地产信息网官网_软件商店下载官方_太原seo管理_百度收录快速提交

石家庄房地产信息网官网_软件商店下载官方_太原seo管理_百度收录快速提交

2024/10/14 14:12:25 来源:https://blog.csdn.net/c565114/article/details/142909059  浏览:    关键词:石家庄房地产信息网官网_软件商店下载官方_太原seo管理_百度收录快速提交
石家庄房地产信息网官网_软件商店下载官方_太原seo管理_百度收录快速提交

1.右值引用和移动语义

左值和右值的重点区分是能否取地址。

能取地址的是左值(可以是值,也可以是表达式),不能取地址的是右值。

1.1 什么是左值

1.2 什么是右值

1.2.1 常见的右值

常见右值:常数(10),匿名对象,函数返回值(函数返回出去的是个临时对象),x+y这个表达式的结果也是右值。

但是像这种返回的就是个左值,因为它返回的是个左值引用。

补充:匿名对象是右值,有名的是左值。

1.3 右值引用

左值引用就是给左值取别名,右值引用就是给右值取别名。

上图为右值引用。

还可以通过强转的方式让左值引用 引用一个右值

1.4 右值引用的意义

引用的意义:减少拷贝,提高效率。

1.4.1左值引用的场景

左值引用的场景:一个是传引用传参,一个是传引用返回。它们都可以减少拷贝,提高效率。

但是左值引用返回值的问题没有彻底解决:如果返回值是func2中的局部对象,不能用引用返回(因为出了作用域,局部对象要销毁)!

1.4.2移动构造和移动赋值

为了解决这个问题,C++11在构造,拷贝构造的基础上重载出了移动构造:

编译器会自动匹配最合适的一个去调用。

理解移动构造:C++把右值细分为纯右值(内置类型)和将亡值(自定义类型)。而根据上文中介绍的内容我们发现,将亡值的生命周期其实并不长(一般就是其所在的那一行),为了减少拷贝,移动构造其实就是“夺舍”的做法,把将亡值中的数据换给我,把我的数据换给将亡值。这样进行简单的数据交换的效率要比深拷贝的效率高很多很多!这么做几乎可以把拷贝的效率拉到极致,这也是为何C++十分高效的重要原因!(移动赋值也是利用这个原理)。

移动构造和移动赋值提高了传值返回的效率:

图中的str虽然为左值,但是有了移动构造之后,编译器会把它们识别成右值,从而调用移动构造。

有了右值引用重载出来的移动构造,在自定义类型传参时,那些将亡值会走移动构造,将它们的资源转移过去,避免走深拷贝,从而将效率拉到极致。

同样的,有了移动构造和移动赋值之后,编译器会自动把str识别成右值,先调用移动构造,然后再调用移动赋值。

举例:验证移动构造

move可以将左值转化成右值,然后调用移动构造,将str中的资源转移到str1中。

1.4.3补充知识

1.

右值引用本身是左值(s1是左值)。只有右值引用是左值,才能实现资源的交换(移动构造,移动赋值)。

2.

3.

上文所讲的是针对自定义类型中深拷贝的类,因为深拷贝的类才有转移资源的说法,才有效率上的提升。

对于内置类型和浅拷贝的类没有转移资源的说法,效率也不会有提升。

1.5 万能引用

图中的这个模板是万能引用,它可以推导出右边的四个函数。

但是有一个问题:进入函数体中,t全是左值,只能调用Fun的左值引用,不可能调用右值引用。

为了解决这个问题,C++增加了一个东西叫完美转发:

也就是说传左值就不变,传右值会把t转化成右值。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com