1. /*##################################################################
  2. * 右值引用 (C++ 11)
  3. * 主要用于以下:
  4. * 1. 移动语义
  5. * 2. 完美传参 Perfect Forwarding
  6. */
  7. /*
  8. * 什么是右值引用?
  9. */
  10. int a = 5;
  11. int& b = a; // b是左值引用,在C++ 03叫做引用
  12. int&& c // c 右值引用
  13. void printInt(int& i) { cout << "lvalue reference: " << i << endl; }
  14. void printInt(int&& i) { cout << "rvalue reference: " << i << endl; }
  15. int main() {
  16. int i = 1;
  17. printInt(i); // 调用第1个printInt
  18. printInt(6); // 调用第2个printInt
  19. printInt(std::move(i)); // i是左值,先调move(),再调第2个printInt
  20. }
  21. /*
  22. * 函数签名:
  23. *
  24. * int和int&不区分
  25. * int和int&&不区分
  26. *
  27. * int&和int&&区分,也就是可以重载左值引用和右值引用两个
  28. */
  29. /* What's the big deal??? */
  30. class boVector {
  31. int size;
  32. string label;
  33. double* array;
  34. public:
  35. boVector(const boVector& rhs) { // 拷贝构造
  36. size = rhs.size;
  37. array = new double[size];
  38. for (int i=0; i<size; i++) { array[i] = rhs.array[i]; }
  39. }
  40. // boVector(const boVector&& rhs) { // 移动构造
  41. // size = rhs.size;
  42. // array = rhs.array;
  43. // rhs.array = nullptr;
  44. // }
  45. };
  46. void foo_by_value(boVector v) { v.label = "Student's Ages"; } //如果没有右值引用,需要很多不同版本的函数
  47. void foo_by_reference(boVector& v) { v.label = "Student's Ages"; }
  48. boVector createBoVector(); // Creates a boVector
  49. void main() {
  50. boVector reusable = createBoVector();
  51. foo_by_value(reusable);
  52. ...
  53. boVector tmp= createBoVector();
  54. foo_by_reference(tmp);
  55. }
  56. /* Notes:
  57. boVector(const boVector&& rhs) { // 移动构造
  58. size = rhs.size;
  59. array = rhs.array;
  60. }
  61. boVector reusable = createBoVector();
  62. foo(reusable);
  63. */
  64. // 练习:
  65. boVecotor b = createBoVector();
  66. // Approach 1:
  67. void foo(boVector & v);
  68. foo(b);
  69. // Approach 2:
  70. void foo(boVector && v);
  71. foo(std::move(b));
  72. // 问题:两种方法的相同点和不同点
  73. // 两者参数传递上都不需要深拷贝
  74. // 后者将所有权也传递, move后不能再使用
  75. /*
  76. * Note 1: 右值引用最主要的使用地方是重载拷贝构造和拷贝赋值,得到移动语义
  77. */
  78. X& X::operator=(X const & rhs);
  79. X& X::operator=(X&& rhs);
  80. /* Note 2: 所以得STL容器都实现了移动语义,这意味着:
  81. * a. 只要切换到C++ 11,代码不做任何改变程序就能变快
  82. * b. 使用值传递的频率更高了
  83. */
  84. vector<int> foo() { ...; return myvector; } //可以直接返回
  85. void goo(vector<int>& arg); // 当需要使用参数将goo中处理之后的数据带回外面,需要用引用传递
  86. /* 移动构造:
  87. * 目的:避免不必要的深拷贝
  88. * 1. 当既需要传引用又需要传值得时候,移动构造很有用
  89. * 2. 移动构造允许你对移动对象那个部分进行细微的控制
  90. */
  91. // 陷阱:右值引用是一个右值么?
  92. boVector(const boVector && rhs) {
  93. cout << "Move constructor.\n";
  94. size = rhs.size;
  95. array = rhs.array;
  96. overload(rhs);
  97. }
  98. overload(boVector& v) { cout << "by lvalue."; }
  99. overload(boVector&& v) { cout << "by rvalue."; }

C++11--右值引用(移动语义)的更多相关文章

  1. 关于C++11右值引用和移动语义的探究

    关于C++11右值引用和移动语义的探究

  2. C++11右值引用

    [C++11右值引用] 1.什么是左值?什么是右值? 左值是表达式结束后依然存在的对象:右值是表达式结束时就不再存在的对象. 2.std::move的作用是什么? std::move用于把任意类型转化 ...

  3. C++11 右值引用和转移语义

    新特性的目的 右值引用 (Rvalue Referene) 是 C++ 新标准 (C++11, 11 代表 2011 年 ) 中引入的新特性 , 它实现了转移语义 (Move Sementics) 和 ...

  4. C++11 右值引用 与 转移语义

    新特性的目的 右值引用(R-value Reference)是C++新标准(C++11, 11代表2011年)中引入的新特性,它实现了转移语义(Move Semantics)和精确传递(Perfect ...

  5. c++11 右值引用和移动语义

    什么是左值.右值 最常见的误解: 等号左边的就是左值,等号右边的就是右值 左值和右值都是针对表达式而言的, 左值是指表达式结束后依然存在的持久对象 右值是指表达式结束时就不再存在的临时对象区分: 能对 ...

  6. [c++11]右值引用、移动语义和完美转发

    c++中引入了右值引用和移动语义,可以避免无谓的复制,提高程序性能.有点难理解,于是花时间整理一下自己的理解. 左值.右值 C++中所有的值都必然属于左值.右值二者之一.左值是指表达式结束后依然存在的 ...

  7. C++ 11 右值引用

    C++11中引入的一个非常重要的概念就是右值引用.理解右值引用是学习“移动语义”(move semantics)的基础.而要理解右值引用,就必须先区分左值与右值. 注意:左值右值翻译可能有些问题 *L ...

  8. C++ 11 右值引用以及std::move

    转载请注明出处:http://blog.csdn.net/luotuo44/article/details/46779063 新类型: int和int&是什么?都是类型.int是整数类型,in ...

  9. 【转】C++ 11 右值引用的理解

    右值引用的目的之一,是为了C++中一个比较影响性能的问题:拷贝临时对象,例如,在 int foo(){ ... } int x; x = foo(); 中,在第三句中,发生了以下的事情: 1.销毁 x ...

  10. C++11右值引用和std::move语句实例解析

    关键字:C++11,右值引用,rvalue,std::move,VS 2015 OS:Windows 10 右值引用(及其支持的Move语意和完美转发)是C++0x将要加入的最重大语言特性之一.从实践 ...

随机推荐

  1. 无根树同构_hash

    先贴上地址 https://vjudge.net/problem/HDU-5732 判断有根树同构: 1. 直接用括号最小表示法 2. 利用括号最小表示法的思想进行hash 判断无根树同构: 1. 找 ...

  2. 【bug-劫持】深信服劫持

    深信服的 HTTP 劫持有办法解决嘛 劫持js 当前页面打开下载地址,chrome是弹出保存窗口不刷新页面的,但劫持了就刷新页面了 连wifi(电信)和4g(联通)都一样

  3. Django中Ajax处理

    1.大部分和Flask中相同. 2.Django处理JSON,主要是对于查询结果集处理. 使用Django提供的序列化的类来完成QuerySet到JSON字符串的转换 from django.core ...

  4. MyBatis #{} 取值注意事项

    正确写法#{key} 错误写法#{key } #{}中不能加空格,不然会报错

  5. NYOJ 85:有趣的数(打表,规律)

    85-有趣的数 内存限制:64MB 时间限制:3000ms 特判: No 通过数:8 提交数:12 难度:2 题目描述: 把分数按下面的办法排成一个数表. 1/1 1/2 1/3 1/4- 2/1 2 ...

  6. NET Core 实战 Dapper 扩展数据访问

    NET Core 实战:基于 Dapper 扩展你的数据访问方法 一.前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类帮我们实 ...

  7. review

    一.123 第二部分:面向对象 . 谈谈你对面向对象的认识. . 约束 Java: - 接口,约子类中必须包含某个方法(约束). Interface IMessage: def func1(self) ...

  8. 12 IO流

    File类:构造方法    * File(String pathname):根据一个路径得到File对象    * File(String parent, String child):根据一个目录和一 ...

  9. while与do/while循环

    while循环1.格式:初始化条件while(循环条件){循环体迭代条件}题目:100以内偶数的输出及其和(while语句) public class V{ public static void ma ...

  10. 深入浅出Node.js---Connect模块解析 。转载

    文章地址:https://blog.csdn.net/zhangyuan19880606/article/details/51509205 1 Connect模块背景 Node.js的愿望是成为一个能 ...