问题 重新分配智能指针


一般来说做智能指针如 std::unique_ptr 和 Glib::RefPtr 在重新分配指向另一个对象时删除它们的对象,因为它们是持有该给定对象的唯一指针(显然暗示在 std::unique_ptr)?


3858
2017-12-04 19:38


起源



答案:


对于 unique_ptr::reset,[unique.ptr.single.modifiers] / 4:

效果:分配 p 到存储的指针,然后 如果存储指针的旧值, old_p,不等于 nullptr,电话    get_deleter()(old_p)

或移动赋值运算符, operator=(unique_ptr&& u) 在[unique.ptr.single.asgn] / 2中:

从中转移所有权 u 至 *this 仿佛 通过电话    reset(u.release()) 其次是 get_deleter() = std::forward<D>(u.get_deleter())

(相当于其他赋值运算符模板)


对于 shared_ptr,重新分配有点不同。 shared_ptr 永远不会销毁一个引用的对象,当它不是最后一个拥有它的对象时,所以我们假设给出了它。
shared_ptr::reset(Y*) 在[util.smartptr.shared.mod] / 3中指定:

效果: 相当于 shared_ptr(p).swap(*this)

但很明显,临时在函数调用结束时被销毁,破坏了hold对象(如果适用)。
 这是相同的行为 operator=(shared_ptr<> const&) has,[util.smartptr.shared.assign] / 1和4:

效果: 相当于 shared_ptr(r).swap(*this)

...移动赋值运算符(模板), r 是 shared_ptr<>&&

效果: 相当于 shared_ptr(std::move(r)).swap(*this)

如果 *this 是最后拥有这个对象的,然后现在是临时的 - 它将在内部被摧毁。


对于 Glib::RefPtr 场景类似于 shared_ptr:复制赋值运算符(和赋值运算符模板)使用相同的语义定义。如果是当前的 RefPtr 被分配给其他东西,当前保持对象引用计数器递减并且如果结果计数器值为零则销毁它。


12
2017-12-04 19:43



RefPtr <Something> something = getSomething(); something = getSomethingElse();工作正常。您不应该使用RefPtr :: swap()。当然,这里的重新分配只会减少对第一个Something的引用,而不是删除它。这是一个参考计数 共享 智能指针。 - murrayc
@murrayc我第一次看过它时一定是误读了文档。谢谢! - Columbo


答案:


对于 unique_ptr::reset,[unique.ptr.single.modifiers] / 4:

效果:分配 p 到存储的指针,然后 如果存储指针的旧值, old_p,不等于 nullptr,电话    get_deleter()(old_p)

或移动赋值运算符, operator=(unique_ptr&& u) 在[unique.ptr.single.asgn] / 2中:

从中转移所有权 u 至 *this 仿佛 通过电话    reset(u.release()) 其次是 get_deleter() = std::forward<D>(u.get_deleter())

(相当于其他赋值运算符模板)


对于 shared_ptr,重新分配有点不同。 shared_ptr 永远不会销毁一个引用的对象,当它不是最后一个拥有它的对象时,所以我们假设给出了它。
shared_ptr::reset(Y*) 在[util.smartptr.shared.mod] / 3中指定:

效果: 相当于 shared_ptr(p).swap(*this)

但很明显,临时在函数调用结束时被销毁,破坏了hold对象(如果适用)。
 这是相同的行为 operator=(shared_ptr<> const&) has,[util.smartptr.shared.assign] / 1和4:

效果: 相当于 shared_ptr(r).swap(*this)

...移动赋值运算符(模板), r 是 shared_ptr<>&&

效果: 相当于 shared_ptr(std::move(r)).swap(*this)

如果 *this 是最后拥有这个对象的,然后现在是临时的 - 它将在内部被摧毁。


对于 Glib::RefPtr 场景类似于 shared_ptr:复制赋值运算符(和赋值运算符模板)使用相同的语义定义。如果是当前的 RefPtr 被分配给其他东西,当前保持对象引用计数器递减并且如果结果计数器值为零则销毁它。


12
2017-12-04 19:43



RefPtr <Something> something = getSomething(); something = getSomethingElse();工作正常。您不应该使用RefPtr :: swap()。当然,这里的重新分配只会减少对第一个Something的引用,而不是删除它。这是一个参考计数 共享 智能指针。 - murrayc
@murrayc我第一次看过它时一定是误读了文档。谢谢! - Columbo


对于 的unique_ptr 答案是肯定的:

对象被破坏,并且当其中任何一个被释放时,它的内存被释放   发生以下情况S:

  • unique_ptr管理对象被销毁
  • 通过operator =或reset()为unique_ptr管理对象分配了另一个指针。

使用可能由用户提供的删除器来销毁该对象   调用Deleter(ptr)。删除器调用对象的析构函数   并分配记忆。


4
2017-12-04 19:43