当成员是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& other) : Test() *ptr = *(other.ptr);
或 Test(int i = 0) : ptr(make_unique<int>(i)) Test(const Test& other) : Test(*(other.ptr))
。这样Test
的每个实例都可以平等地使用make_unique
,并且在类中有一个分配点,而不是让默认构造的实例使用make_unique
,而复制的实例使用new
。但是,这只是我。无论哪种方式都会“工作”。
@RemyLebeau 好点。在这种情况下,我什至可能不会考虑以任何一种方式实现它,因为复制的意义有限。【参考方案2】:
发生了什么事?
您已从裸指针转换为强制所有权语义的指针。一个很聪明的人。
这确实是unique_ptr
的目的。
它强制执行唯一所有权。
你不能复制它;只移动它。
如果您确实需要 Test
可复制并能够共享 int
s,您可能正在寻找 shared_ptr
。
【讨论】:
感谢您的回答。但是我在哪里可以找到这样的规则:当类具有 unique_ptr 成员时,从类中删除复制构造函数? 编译器必须调用已删除的 unique_ptr 的复制构造函数。 MSVC 发出以下错误'Test::Test(const Test &)': 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?