【问题标题】:For what is the move constructor and move assignment constructor in Unique Pointers needed?需要唯一指针中的移动构造函数和移动赋值构造函数是什么?
【发布时间】:2015-08-04 19:46:47
【问题描述】:

我有一个unique_ptr 的简化示例。我想知道唯一指针中的移动构造函数和移动赋值运算符是什么? 如果我理解正确的移动构造函数(和传递右值),这两行代码的结果应该是一样的。

UniquePointer<T> a(new T);
UniquePointer<T> a(UniquePointer<T>(new T));

这里是简化的UniquePointer 代码:

template<typename T> class UniquePointer {
    T* m_ptr;
public:
    UniquePointer(const UniquePointer&) = delete;
    UniquePointer& operator=(const UniquePointer&) = delete;
    UniquePointer(UniquePointer&& rhs);
    UniquePointer& operator=(UniquePointer&& rhs);
    UniquePointer(T* ptr) : m_ptr(ptr) { }
    T* operator->() const { return m_ptr; }
    T& operator*() const { return *m_ptr; }
    T* get() const { return m_ptr; }
    ~UniquePointer() { delete m_ptr; }
};

【问题讨论】:

  • 返回所有权:auto unique = std::make_unique()
  • 不支持移动语义,你不能把它放在向量中

标签: c++ c++11 smart-pointers move-semantics unique-ptr


【解决方案1】:

首先调用常规构造函数UniquePointer(T* ptr)(不是移动构造函数)。第二次调用移动构造函数UniquePointer(UniquePointer&amp;&amp; rhs),因为你传入了UniquePointer类型的右值,复制构造函数被删除。

你也需要移动构造函数

UniquePtr<T> ptr = std::move(some_old_unique_ptr);

在这种情况下,您需要从旧的std::move,因为旧的是lvalue。在已构造的对象上调用移动赋值运算符

ptr = std::move(yet_another_ptr); // invokes the move assignment operator

至于你为什么需要它们,那是因为设计。此类对象是不可复制的,因此您需要移动它们。

【讨论】:

  • 如果我理解你的话,它需要支持标准库 std:move() 的移动操作并且没有其他优势?
  • @maniac 您必须了解移动语义的含义。它允许你“窃取”右手边的资源,在处理“昂贵”的复制对象时非常有用。在某些情况下您想防止复制(例如unique_ptr),因此移动是唯一的选择。是的,在这种情况下,您需要移动构造函数和移动赋值运算符,否则将无法传递您的对象。旁注:std::move 只对右值进行强制转换,不移动任何东西。
【解决方案2】:

如果您需要将所有权从一个范围转移到另一个范围,则需要一个单独的对象。而且由于您不能(也不想)复制unique_ptr,这意味着您需要移动它。例如,从函数返回 unique_ptr 时。

std::unique_ptr<Foo> func()
{
    std::unique_ptr<Foo> ptr(new Foo);
    ...
    return ptr;
}

这需要移动构造函数或复制构造函数。另一个常见用例是从构造函数参数初始化类成员。

class Widget
{
public:
    Widget(std::unique_ptr<Foo> _foo_ptr)
       :foo_ptr(std::move(_foo_ptr))
    {}
private:
    std::unique_ptr<Foo> foo_ptr;
};

【讨论】:

    【解决方案3】:

    std::unique_ptr 需要移动构造函数和移动赋值运算符,因为它是不可复制的,因此是唯一的对象。由于它是不可复制的,因此需要一种方法将其传递给事物,从而移动操作来处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-22
      • 2019-01-22
      • 2021-05-31
      • 2015-03-03
      • 2016-09-13
      • 2016-05-19
      • 1970-01-01
      • 2017-01-10
      相关资源
      最近更新 更多