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. 基础数据类型-dict

    字典Dictinary是一种无序可变容器,字典中键与值之间用“:”分隔,而与另一个键值对之间用","分隔,整个字典包含在{}内: dict1 = {key1:value1, key ...

  2. Linux中常用的关机和重新启动命令

    hutdown.halt.reboot以及init,它们都可以达到关机和重新启动的目的,但是每个命令的内部工作过程是不同的,下面将逐一进行介绍. 一.shutdown shutdown命令用于安全关闭 ...

  3. iscroll手册

    概述: 大家在日常工作中最常用的插件是什么,jQurey?Lazyload?但是这些都是在PC端,但是在移动端最常用的插件莫过于iScroll了,iScroll到底是什么东西,应该怎么用?iScrol ...

  4. 11.24Daily Scrum(2)

    人员 任务分配完成情况 明天任务分配 王皓南 实现网页上视频浏览的功能.研究相关的代码和功能.996 数据库测试 申开亮 实现网页上视频浏览的功能.研究相关的代码和功能.997 实现视频浏览的功能 王 ...

  5. Java Class Object

    Object类 它是所有类的基类. public class Person { } //实际上是 public class Person extends Object { } Object类的方法 t ...

  6. 第八次作业——项目UML设计

    分工及贡献分评定 成员 参与 贡献比例 朱跃安(031602348) 类图 13% 后敬甲(031602409) 实体关系图+博客整理 14.5% 林志华(031602128) 用例图+活动图 14. ...

  7. php中的<?= ?>替换<?php echo ?>

    首先修改PHP.ini文件.如下: 1. 将short_open_tag = Off 改成On 开启以后可以使用PHP的短标签:<? ?> <?= $test ?>来代替 &l ...

  8. 使用tc来控制网络流量

    https://blog.csdn.net/qinyushuang/article/details/46611709 tc实际操控网络的流量 解释网络tc的架构,从架构上分析tc,与netfilter ...

  9. jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失

    jsp当做第二个servlet  request的生命周期   请求 响应  不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束  request的域消失

  10. C# 利用FTP自动下载xml文件后利用 FileSystemWatcher 监控目录下文件变化并自动更新数据库

    using FtpLib; using System; using System.Collections.Generic; using System.ComponentModel; using Sys ...