zoukankan      html  css  js  c++  java
  • 翻译「C++ Rvalue References Explained」C++右值引用详解 Part2:Move语义

    本文为第二部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html

    Move语义

    假设x是一个类,其含有一个指针或者某些资源的句柄(handle)。写作m_pResource。由这个资源,我的意思是包括构造、克隆、析构都认真考虑在内的,一个绝佳的例子是std::vector。它可以在一个分配的内存数组中包含一个对象集合。接下来,从逻辑上,对于x的拷贝赋值操作符一般如下:

    X& X::operator=(X const & rhs)
    {
      // [...]
      // 析构 m_pResource指向的资源. 
      // 对rhs.m_pResource所指向的资源做一份克隆,然后
      // 再把它附在 m_pResource上.
      // [...]
    }

    因为类似的原因这也适用于拷贝构造函数。现在假设x被如下使用:

    X foo();
    X x;
    // x也许被通过多种方式使用
    x = foo();

    在最后一行执行前:

    • 析构了被x持有的资源
    • 克隆了从foo返回的临时变量
    • 析构了那个临时变量并从而释放了它指向的资源

    显而易见的,这样是可行的,但还有一种更有效率的做法,那就是交换(swap)x和临时变量中的对资源的指针或者句柄(handles),然后让临时变量的析构器析构原来x的资源。换一种说法,在这种特别的情况下,位于赋值右手边的是右值。我们希望拷贝构造函数如下表现:

    // [...]
    // 交换m_pResource和rhs.m_pResource
    // [...]

    这被称作Move语义。在C++11中,这种条件性的行为可以通过如下重载来实现:

    X& X::operator=(<mystery type> rhs)
    {
      // [...]
      // 交换this->m_pResource和rhs.m_pResource
      // [...]  
    }

    因为我们定义了一个对于拷贝构造函数的重载,我们的「mystery type」必须本质上是一个引用:我们当然想让右手边的值可以通过引用传递给我们。而且,我们期望mystery type有如下的行为:当面临到原始的引用类型和mystery type的重载选择时,右值一定优先选择mystery type的重载,而左值一定优先选择原始的引用类型。

    如果你现在意识到在上文中「右值引用」就是指代「mystery type」的话,那么你已经从本质上看到了右值引用的定义。

  • 相关阅读:
    windows下Qt5.1.0配置android环境搭建 good
    Qt Focus事件,FocusInEvent()与FocusOutEvent()
    Python框架之Django
    WITH (NOLOCK)浅析
    区域、模板页与WebAPI初步
    对象映射工具AutoMapper介绍
    .NET大型B2C开源项目nopcommerce解析——项目结构
    企业管理系统集成
    oracle中sql语句的优化
    C#可扩展编程之MEF
  • 原文地址:https://www.cnblogs.com/harrywong/p/move-semantics.html
Copyright © 2011-2022 走看看