c++ - unique_ptr 的 move 构造函数的实现问题

标签 c++ move-semantics unique-ptr move-constructor

我正在尝试编写一个 unique_ptr 实现。我正在努力编写 move 构造函数。这是我的问题:

  1. 当我将 move 构造函数标记为默认时,我的资源被删除了两次,当我 move 时分配一个指针(auto foo2 = std::move(foo);下面)- 为什么?
  2. 当我尝试像这样在 move 构造函数中分配底层指针时 *rhs = nullptr (见下面的实现),编译器说 *rhs 是一个右值,我不能给它分配任何东西。
  3. 最后,rhs.m_ptr = nullptr 起作用了。为什么它有效,而 *rhs = nullptr 无效?

我的代码:

#include <iostream>

namespace my
{
template <class T>
class unique_ptr
{
public:
    unique_ptr()
    {
        m_ptr = new T;
    }
    unique_ptr(const unique_ptr&) = delete;
    // move constructor
    unique_ptr(unique_ptr&& rhs)  // = default deletes m_ptr twice
    {
        m_ptr = *rhs;
        rhs.m_ptr = nullptr;  // *rhs = nullptr doesn't work (*rhs is an rvalue)
    }
    ~unique_ptr()
    {
        delete m_ptr;
    }
    T* operator->()
    {
        return m_ptr;
    }
    T* operator*()
    {
        return m_ptr;
    }
    unique_ptr& operator=(const unique_ptr&) = delete;
    // no move assignment yet
private:
    T* m_ptr;
};

}  // namespace my

struct Foo
{
    Foo()
    {
        std::cout << "Foo" << std::endl;
    }
    ~Foo()
    {
        std::cout << "~Foo" << std::endl;
    }
    void printHello()
    {
        std::cout << "Hello" << std::endl;
    }
};

int main()
{
    my::unique_ptr<Foo> foo;
    foo->printHello();

    auto foo2 = std::move(foo);

    return 0;
}

附带说明一下,显然我可以将不带任何模板参数的 unique_ptr 传递给 unique_ptr 类模板内的方法。编译器是否只是假设它是 T?

请丢弃与所述问题无关的任何其他实现错误。正在进行中。

最佳答案

1) 默认 move 构造函数不知道您的类的语义。所以它 move 了指针 rhs,但它不会重置另一个指针,它也会在另一个析构函数中被删除。

2) *rhs 调用operator* 并返回一个临时/右值T*,内部指针的拷贝,并且不是与应返回 T&const T& 的常用 operator* 一致。

3) 参见 2. 你正在返回一个临时对象。

最后,你应该拥有:

unique_ptr(unique_ptr&& rhs)  // = default deletes m_ptr twice
: m_ptr(rhs.m_ptr)
{
    rhs.m_ptr = nullptr;  // *rhs = nullptr doesn't work (*rhs is an rvalue)
}

T& operator*() {return *m_ptr;}
const T& operator*() const {return *m_ptr;}

等等。

关于c++ - unique_ptr 的 move 构造函数的实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53801896/

相关文章:

C++ 堆栈实现

c++ - 为什么一个工作,一个崩溃?

c++ - 为什么 C++11 对值参数有隐式 move ,但对右值参数没有?

c++ - 是否可以在 std::unique<T[ ]> 上应用 std::sort?

c++ - 如何使用std::vector <unique_ptr <T >>作为默认参数

c++ - 如何在 C++ 中寻找特定行以附加数据或将数据附加到最后一行

c++ - 不会匹配模板函数

c++ - 无限制 union 的 move 构造函数因 invalid_pointer 而崩溃

c++ - 何时在 C++ 中提供自定义交换函数?

c++ - 为什么我的 unique_ptr 认为它有一个空函数指针删除器?