【重学C++】04 | 说透C++右值引用、移动语义、完美转发(上) ...

打印 上一主题 下一主题

主题 903|帖子 903|积分 2709

文章首发

【重学C++】04 | 说透C++右值引用、移动语义、完美转发(上)
引言

大家好,我是只讲技术干货的会玩code,今天是【重学C++】的第四讲,在前面《03 | 手撸C++智能指针实战教程》中,我们或多或少接触了右值引用和移动的一些用法。
右值引用是 C++11 标准中一个很重要的特性。第一次接触时,可能会很乱,不清楚它们的目的是什么或者它们解决了什么问题。接下来两节课,我们详细讲讲右值引用及其相关应用。内容很干,注意收藏!
左值 vs 右值

简单来说,左值是指可以使用&符号获取到内存地址的表达式,一般出现在赋值语句的左边,比如变量、数组元素和指针等。
  1. int i = 42;
  2. i = 43; // ok, i是一个左值
  3. int* p = &i; // ok, i是一个左值,可以通过&符号获取内存地址
  4. int& lfoo() { // 返回了一个引用,所以lfoo()返回值是一个左值
  5.         int a = 1;
  6.         return a;
  7. };
  8. lfoo() = 42; // ok, lfoo() 是一个左值
  9. int* p1 = &lfoo(); // ok, lfoo()是一个左值
复制代码
相反,右值是指无法获取到内存地址的表达是,一般出现在赋值语句的右边。常见的有字面值常量、表达式结果、临时对象等。
  1. int rfoo() { // 返回了一个int类型的临时对象,所以rfoo()返回值是一个右值
  2.         return 5;
  3. };
  4. int j = 0;
  5. j = 42; // ok, 42是一个右值
  6. j = rfoo(); // ok, rfoo()是右值
  7. int* p2 = &rfoo(); // error, rfoo()是右值,无法获取内存地址
复制代码
左值引用 vs 右值引用

C++中的引用是一种别名,可以通过一个变量名访问另一个变量的值。

上图中,变量a和变量b指向同一块内存地址,也可以说变量a是变量b的别名。
在C++中,引用分为左值引用和右值引用两种类型。左值引用是指对左值进行引用的引用类型,通常使用&符号定义;右值引用是指对右值进行引用的引用类型,通常使用&&符号定义。
  1. class X {...};
  2. // 接收一个左值引用
  3. void foo(X& x);
  4. // 接收一个右值引用
  5. void foo(X&& x);
  6. X x;
  7. foo(x); // 传入参数为左值,调用foo(X&);
  8. X bar();
  9. foo(bar()); // 传入参数为右值,调用foo(X&&);
复制代码
所以,通过重载左值引用和右值引用两种函数版本,满足在传入左值和右值时触发不同的函数分支。
值得注意的是,void foo(const X& x);同时接受左值和右值传参。
  1. void foo(const X& x);
  2. X x;
  3. foo(x); // ok, foo(const X& x)能够接收左值传参
  4. X bar();
  5. foo(bar()); // ok, foo(const X& x)能够接收右值传参
  6. // 新增右值引用版本
  7. void foo(X&& x);
  8. foo(bar()); // ok, 精准匹配调用foo(X&& x)
复制代码
到此,我们先简单对右值和右值引用做个小结:

  • 像字面值常量、表达式结果、临时对象等这类无法通过&符号获取变量内存地址的,称为右值。
  • 右值引用是一种引用类型,表示对右值进行引用,通常使用&&符号定义。
右值引用主要解决一下两个问题:

  • 实现移动语义
  • 实现完美转发
这一节我们先详细讲讲右值是如何实现移动效果的,以及相关的注意事项。完美转发篇幅有点多,我们留到下节讲。
复制 vs 移动

假设有一个自定义类X,该类包含一个指针成员变量,该指针指向另一个自定义类对象。假设O占用了很大内存,创建/复制O对象需要较大成本。
[code]class O {public:        O() {                std::cout

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

美丽的神话

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表