前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++右值引用和移动语义学习小结

C++右值引用和移动语义学习小结

作者头像
linjinhe
发布2018-09-26 11:20:41
7460
发布2018-09-26 11:20:41
举报
文章被收录于专栏:linjinhe的专栏linjinhe的专栏

在 C++11 之前,将一个对象移动(move)到另一个对象的通用做法只有 copy constructor 或者 copy assignment ,然后销毁原来的对象。如果这个对象的创建涉及动态内存分配的话,copy constructor 或者 copy assignment 的开销就可能比较大。

从 C++11 开始,C++ 引入了移动语义(move semantics)。由此 C++11 的 class 也多了两个特殊的成员函数 —— move constructor 和 move assignment。 引入移动语义,首先要做的第一件事就是,如何确定该用 move 还是 copy ? 为此 C++11 引入了右值引用这个概念 —— 在 C++ 里所有的右值都可以被移动。

这里又有了另一个问题:什么是右值引用、右值?相对的还有左值引用、左值? 左值与右值这两概念是从 C 语言中传承而来的。在 C 语言中,左值指的是既能够出现在等号左边也能出现在等号右边的变量(或表达式),右值指的则是只能出现在等号右边的变量(或表达式)。 左值可以取到其内存地址,右值不能。左值与右值的根本区别在于能否获取内存地址。 左值引用和右值引用,其实就是左值的引用和右值的引用。他们俩都是引用,区别在于引用的数据是啥。 注意,左值引用和右值引用都是左值。

下面举几个简单的列子:

代码语言:javascript
复制
int i = 42;                 // i 是个左值,42 是个右值
int& r = i;                 // r 是个左值引用
int&& rr = i;               // 错误,不能将左值 i 绑定到右值引用 rr 上
int&& rr1 = std::move(i);    // std::move 将 i 强制转换成一个右值
int &r2 = i * 42;           // 错误: i * 42 是一个右值,不能绑定到一个左值引用
const int &r3 = i * 42;     // 可以将一个右值绑定到一个 const 的左值引用
int &&rr2 = i * 42;         // 将右值绑定到右值引用

从上面的例子可以看到,有两种引用可以绑定到右值:const 左值引用和右值引用

当传入的对象是右值且支持 move constructor 或 move assignment 时,C++ 会使用移动语义的函数。如果不支持移动语义的函数,无论传入的对象是右值还是左值,C++ 还是会使用复制语义的函数。 因为左值引用和右值引用其实都是左值, C++11 提供了一个函数 std::move 可以将一个对象强制转换成右值(rvalue)。

移动语义的出现,一方面可以让编译器在某些情况下,使用 move 而不是 copy 来提升程序性能。另一方面,让一些 move-only 的类型在语义上更加明确,如 std::unique_ptrstd::futurestd::thread

更多关于右值引用、移动语义的内容,请参考

  • C++ Primer 5th, 13.6 Moving Objects
  • Effective Mordern C++, Chapter 5 Rvalue References, Move Semantics, and Perfect Forwarding

最后,附上之前整理的电子书下载链接:C++ 学习资料整理(电子书)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.08.25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档