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」的话,那么你已经从本质上看到了右值引用的定义。

  • 相关阅读:
    155. 最小栈
    160. 相交链表
    PAT 1057 Stack
    PAT 1026 Table Tennis
    PAT 1017 Queueing at Bank
    PAT 1014 Waiting in Line
    PAT 1029 Median
    PAT 1016 Phone Bills
    PAT 1010 Radix
    PAT 1122 Hamiltonian Cycle
  • 原文地址:https://www.cnblogs.com/harrywong/p/move-semantics.html
Copyright © 2011-2022 走看看