当成员是unique_ptr时删除了复制构造函数[重复]

Posted

技术标签:

【中文标题】当成员是unique_ptr时删除了复制构造函数[重复]【英文标题】:Deleted copy constructor when member is an unique_ptr [duplicate] 【发布时间】:2019-01-22 15:55:47 【问题描述】:

这段代码运行良好:

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;

发生了什么事?

【问题讨论】:

当然unique_ptr 没有复制构造函数,只有移动构造函数。如果您想复制Test,请使用shared_ptr(或按照链接答案的建议进行深层复制)。 提示在名称中。如果每个人都能拥有一个指针,它就不是唯一的指针了。 其实原代码不是好的。它有内存泄漏,切换到std::unique_ptr 允许编译器防止这种情况(通过不允许您的代码)。 【参考方案1】:

发生了什么事?

您不能创建第二个 Test 实例,因为这意味着您需要一个 unique_ptr 的副本,这是不可能的。 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;

【讨论】:

@user463035818 但这不是指针的副本。您现在有两个不同的指针指向两个不同的对象,这与 OP 的第一个示例不同。 @user463035818 我们可能正在讨论答案的不同部分:P @LightnessRacesinOrbit 我可能不得不重新加载才能看到编辑内容......现在我对答案很好。 cmets 已删除 我可能会像这样实现复制构造函数:Test(const Test&amp; other) : Test() *ptr = *(other.ptr); Test(int i = 0) : ptr(make_unique&lt;int&gt;(i)) Test(const Test&amp; other) : Test(*(other.ptr)) 。这样Test 的每个实例都可以平等地使用make_unique,并且在类中有一个分配点,而不是让默认构造的实例使用make_unique,而复制的实例使用new。但是,这只是我。无论哪种方式都会“工作”。 @RemyLebeau 好点。在这种情况下,我什至可能不会考虑以任何一种方式实现它,因为复制的意义有限。【参考方案2】:

发生了什么事?

您已从裸指针转换为强制所有权语义的指针。一个很聪明的人。

这确实是unique_ptr的目的

它强制执行唯一所有权

你不能复制它;只移动它。

如果您确实需要 Test 可复制并能够共享 ints,您可能正在寻找 shared_ptr

【讨论】:

感谢您的回答。但是我在哪里可以找到这样的规则:当类具有 unique_ptr 成员时,从类中删除复制构造函数? 编译器必须调用已删除的 unique_ptr 的复制构造函数。 MSVC 发出以下错误'Test::Test(const Test &amp;)': attempting to reference a deleted function @KeyB0rys 请参阅:timsong-cpp.github.io/cppwp/class.copy.ctor#10 @KeyB0rys 正如 Nathan 所示。从逻辑上讲,当类的一部分被定义为不可复制时,如何复制该类?这没有任何意义。

以上是关于当成员是unique_ptr时删除了复制构造函数[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在构造函数中为成员 unique_ptr 赋予默认值? [复制]

unique_ptr & vector,试图访问已删除的函数,Visual Studio 2013

如何在构造函数中使用删除器初始化 std::unique_ptr?

具有右值删除器的 unique_ptr 构造函数返回 null?

从 initializer_list 构造 std::map<T, unique_ptr<S>> 时出错

复制接口的 std::unique_ptr [关闭]