C++11新标准中的一个最主要的特性就是移动而非拷贝对象的能力。接下来简要介绍一下相关概念。

  • 右值引用

    • 所谓右值引用就是必须绑定到右值的引用。通过 && 而不是 & 来获得右值引用。右值引用有一个重要的性质 — 只能绑定到一个将要销毁的对象。因此我们可以自由的将一个右值引用的资源“移动”到另一个对象中。
    • 一般而言,一个左值表达式表示的是一个对象的身份,而一个右值表达式表示的是对象的值。
    • 类似任何引用,一个右值引用也不过是某个对象的一个名字而已。对于一个常规引用(左值引用),不能将其绑定到要求转换的表达式、字面常量或是返回右值的表达式。右值引用则相反:可以将一个右值引用绑定到这类表达式上,但不能将一个右值引用直接绑定到一个左值上。
      cpp int i = 42; int &r = i; //正确, r 引用 i, 左值引用 int &&r = i; //错误,不能将一个右值引用绑定到一个左值上 int &r2 = i * 42; //错误, i * 42 是一个右值 const int &r3 = i * 42; //正确,可以将一个const的引用绑定到一个右值上 int &&rr2 = i * 42; //正确,将rr2绑定到乘法结果上
      1. 返回左值引用的函数,连同赋值、下标、解引用和前置递增、递减运算符,都是返回左值的表达式的例子。
      2. 返回非引用类型的函数,连同算术、关系、位以及后置递增、递减运算符,都生成右值。我们不能将一个左值引用绑定到这类表达式上,但我们可以将一个const的左值引用和一个右值引用绑定到这类表达式上。

    • 左值持久,右值短暂
      • 左值有持久的状态,而右值要么是字面常量,要么是在表达式求值过程中创建的临时对象。
      • 右值引用指向将要被销毁的对象。因此,可以从绑定到右值引用的对象“窃取”状态,即使用右值引用的代码可以自由接管所引用的对象的资源。
    • 变量是左值,不能将一个右值引用直接绑定到一个变量上,即使这个变量是右值引用类型也不行。
      cpp int &&rr1 = 42; //正确,字面常量是右值 int &&rr2 = rr1; //错误,表达式rr1是左值
    • 标准库的 move 函数
      • 虽然不能将一个右值直接绑定到一个左值上,但可以显式地将一个左值转换为对应的右值引用类型。我们可以通过调用一个名为 move的新标准库函数来获得绑定到左值上的引用。头文件
        cpp int &&rr3 = std::move(rr1); //ok
      • 我们可以销毁一个移后源对象,也可以赋予它新值,但不能使用一个移后源对象的值。
  • 移动构造函数和移动赋值运算符
    • 类似拷贝构造函数,移动构造函数的第一个参数是该类类型的一个引用。不同于拷贝构造函数的是,这个引用参数在移动构造函数中是一个右值引用。与拷贝构造函数相同,任何额外的参数都必须有默认实参。
    • 除了完成资源移动,移动构造函数还必须确保移后源对象处于这样一个状态 — 销毁它是无害的。特别是,一旦资源完成移动,源对象必须不再指向被移动的资源。这些资源的所有权已经归属于新创建的对象。
    • 移动操作、标准库容器和异常
      • 由于移动操作“窃取”资源,它通常不会分配任何资源。因此,移动操作通常不会抛出任何异常。
      • 当编写一个不抛出异常的移动操作时,我们应该将此事通知标准库。除非标准库知道不会抛出异常,否则它会为了处理可能抛出异常这种可能性而做一些额外的工作。
      • 一种通知标准库的方法是将构造函数指明为 noexcept。这个关键字是新标准引入的。
      • 不抛出异常的移动构造函数和移动赋值运算符都必须标记为noexcept.
  • 移后源对象必须可析构
    • 从一个对象移动数据并不会销毁此对象,但有时在移动操作完成后,源对象会被销毁。当我们编写一个移动操作时,必须确保移后源对象进入一个可析构的状态。即将移后源对象的指针成员置为nullptr来实现的。
    • 在移动操作之后,移后源对象必须保持有效的、可析构的状态,但是用户不能对其值进行任何假设。
  • 合成的移动操作
    • 如果一个类定义了自己的拷贝构造函数、拷贝赋值运算符或者析构函数,编译器就不会为它合成移动构造函数和移动赋值运算符了。
    • 只有当一个类没有定义任何自己版本的拷贝控制成员,且类的每个非static数据都可以移动时,编译器才会为它合成移动构造函数和移动赋值运算符。
    • 定义了一个移动构造函数或移动赋值运算符的类必须也定义自己的拷贝操作。否则,这些成员默认被定义为删除的。

C++11新特性,对象移动,右值引用,移动构造函数的更多相关文章

  1. C++ 新特性 笔记 2 右值引用

    C ++ Rvalue引用说明 以下内容,主要是上述链接的摘要 介绍 Rvalue引用是C ++的一个特性,它是随C ++ 11标准添加的.使右值参考有点难以理解的是,当你第一次看到它们时,不清楚它们 ...

  2. C++11新特性之0——移动语义、移动构造函数和右值引用

    C++引用现在分为左值引用(能取得其地址)和 右值引用(不能取得其地址).其实很好理解,左值引用中的左值一般指的是出现在等号左边的值(带名称的变量,带*号的指针等一类的数据),程序能对这样的左值进行引 ...

  3. 【转】C++11 标准新特性: 右值引用与转移语义

    VS2013出来了,对于C++来说,最大的改变莫过于对于C++11新特性的支持,在网上搜了一下C++11的介绍,发现这篇文章非常不错,分享给大家同时自己作为存档. 原文地址:http://www.ib ...

  4. C++11 标准新特性: 右值引用与转移语义

    文章出处:https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) ...

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

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

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

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

  7. C++11新特性:右值引用和转移构造函数

    问题背景 #include <iostream> using namespace std; vector<int> doubleValues (const vector< ...

  8. c++新特性实验(4)声明与定义:右值引用(C++11)

    1.作用 c++11以前,临时对象.字面常量一般情况下不可以再次访问,也不可以修改.右值引用可以解决这个问题. 1.1 实验A #include <iostream> using name ...

  9. C++ 新特性-右值引用

    作为最重要的一项语言特性,右值引用(rvalue references)被引入到 C++0x中.我们可以通过操作符“&&”来声明一个右值引用,原先在C++中使用“&”操作符声明 ...

随机推荐

  1. Python中的import语句

    Python中的import语句是导入一个文件,这条语句主要做三件事: 1 通过一定的方式,搜寻要导入的文件: 2 如果需要,就编译这个文件: 3 运行这个文件 但是,需要注意的是,所有这三个步骤,都 ...

  2. Coins and Queries(map迭代器+贪心)

    题意 n个硬币,q次询问.第二行给你n个硬币的面值(保证都是2的次幂!).每次询问组成b块钱,最少需要多少个硬币? Example Input 5 42 4 8 2 4851410 Output 1- ...

  3. Thunder团队第五周 - Scrum会议7

    Scrum会议7 小组名称:Thunder 项目名称:i阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...

  4. c# 委托初窥

    1.委托可以把方法当作参数在另一个方法中传递和调用 ,委托是方法的快捷方式. 2.委托是一个类. private void BeginSocketThread() { try { IPEndPoint ...

  5. TCP系列27—窗口管理&流控—1、概述

    在前面的内容中我们依次介绍了TCP的连接建立和终止过程和TCP的各种重传方式.接着我们在这部分首先关注交互式应用TCP连接相关内容如延迟ACK.Nagle算法.Cork算法等,接着我们引入流控机制(f ...

  6. mini2440 Nor Flash工作原理分析

    我的mini2440上是只接了一块Nor Flash,型号是S29AL016M90TAI02,这是一块2M Byte,16位宽度的Nor Flash,用于引导扇区的闪存.原理图里面关键的引脚是: 地址 ...

  7. Unity3d学习日记(一)

      闲来无事开始自学unity3d,发现还挺容易入门的,添加资源文件以及用c#编写脚本都很方便.   前面在Unity官方教程上自学了一段时间,跟着教程写了个space_shooter的小游戏,虽然游 ...

  8. UVA 167 R-The Sultan's Successors

    https://vjudge.net/contest/68264#problem/R The Sultan of Nubia has no children, so she has decided t ...

  9. 【Linux】- vi/vim

    所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正 ...

  10. arp获取

    getarp.c /* getarp.c -- This simple program uses an IOCTL socket call to read an entry */ /* from th ...