使用唯一指针进行深拷贝和浅拷贝

7

没有代码只有一个普遍问题。

如果一个类内有一个独特的指针, shallow copy和deep copy的区别是如何相关的?


1
由于 std::unique_ptr<T> 的复制构造函数被删除,编译器无法为包含 std::unique_ptrclass 生成默认的复制构造函数(对于原始指针执行浅拷贝)。当手动实现复制构造函数时,必须使用深拷贝来确保正确性。已弃用的 std::auto_ptr 是一个负面例子。 - test failed in 1.08s
最大的区别在于浅拷贝是不可能的,而深拷贝是可以的。 - molbdnilo
2个回答

7
浅复制会导致双重释放和悬空指针错误,通常是未定义的行为。
由于std::unique_ptr的整体所有权,因此无法使用浅复制。但是,如果类型具有std::shared_ptr类型的成员,则可以按预期工作,因为shared_ptr是引用计数的。
为了更好地解释上述差异,unique_ptr的唯一所有权前提要求unique_ptr(const unique_ptr&)和unique_ptr& operator=(const unique_ptr&)均为=delete; 因为任何一种都会违反该保证。此外,您需要提供某些扩展方法来允许克隆所指向的对象。shared_ptr在任一情况下都涉及增加引用计数,并且不需要克隆。
理论上,您可以从其他可重用池中分配对象,并向您的unique_ptr提供自定义删除器,该删除器什么也不做。但是,如果您想要共享所有权,则只需使用shared_ptr即可。

“浅拷贝会导致双重释放和悬空指针错误,通常是未定义行为。” — 不,这不是真的。默认拷贝才会有这个问题。然而,这与浅拷贝并不相同。有一些浅拷贝的实现既不会出现未定义行为,也不会泄漏(尤其是通过std::shared_ptr)。 - Konrad Rudolph
@KonradRudolph 但默认复制不就是浅复制吗?有什么区别? - Tanveer Badar
不是的。“shallow”只是指浅复制的相反,即在嵌套对象上没有传递性复制构造函数调用。 - Konrad Rudolph
@KonradRudolph 我对你的看法有所不同。我们显然对浅复制的定义有些不同。但是,如果我的观点改变了,我会阅读更多相关内容并在未来更新这个答案。 - Tanveer Badar
1
你可能是想要使用unique_ptr(const unique_ptr&)的复制构造函数,而不是unique_ptr(const T&) - JHBonarius
显示剩余2条评论

2

使用默认的拷贝构造函数对指针进行浅拷贝会导致悬空指针,即指向未分配或已释放内存的指针。

unique_ptr是不可复制的。该指针只能被移动到另一个unique_ptr中或转换为shared_ptrunique_ptr 的整个目的在于仅有一个引用(指针)指向某个内存块。

这意味着,unique_ptr 不支持浅拷贝。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接