成员为unique_ptr时删除副本构造函数

时间:2019-01-22 15:55:47

标签: c++

此代码可以正常工作:

class Test
{
    int* ptr = new int(10);
};

int main()
{       
     Test o;
     Test t = o;
}

但是当我们使用unique_ptr而不是raw ptr时,会出现错误:

error: use of deleted function 'Test::Test(const Test&)'

和示例代码:

class Test
{
     std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{       
     Test o;
     Test t = o;
}

这是怎么回事?

2 个答案:

答案 0 :(得分:6)

  

这是怎么回事?

您无法创建Test的第二个实例,因为这意味着您需要唯一的副本,而不是唯一的。 unique_ptr只能移动。尝试实现移动分配运算符,并像这样移动o

class Test
{
public:
    Test() = default;

    Test(Test&& other) noexcept
        : ptr(std::move(other.ptr))
    {
    }

private:
    std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{
    Test o;
    Test t = std::move(o);
}

如果要复制unique_ptr底层的int,则需要定义一个自定义复制构造函数,如下所示:

class Test
{
public:
    Test() = default;

    Test(const Test& other)
        : 
    ptr(new int(*other.ptr))
    {

    }

    Test(Test&& other) noexcept
        : ptr(std::move(other.ptr))
    {
    }

private:
    std::unique_ptr<int> ptr = std::make_unique<int>(1);
};

int main()
{
    Test o;
    Test t = o;
}

但是,注意,指针指向两个 DIFFERENT 整数。 如果要共享所有权,则必须(并且应该)使用shared_ptr,如下所示:

class Test
{
private:
    std::shared_ptr<int> ptr = std::make_shared<int>(1);
};

int main()
{
    Test o;
    Test t = o;
}

答案 1 :(得分:3)

  

这是怎么回事?

您已经从一个裸指针换成了一个强制执行所有权语义的指针。一个很聪明。

这实际上是unique_ptr 的目的。

它强制执行唯一所有权

您无法复制它;只能移动它。

如果您确实需要Test是可复制的并且能够共享int,那么您可能正在寻找shared_ptr