【问题标题】:Force deleting std::shared_ptr in C++在 C++ 中强制删除 std::shared_ptr
【发布时间】:2019-01-25 19:49:26
【问题描述】:

根据本文第一个答案:Explicitly deleting a shared_ptr

是否可以像下面的代码一样强制删除 std::shared_ptr 及其管理的对象?

do {
    ptr.reset();
} while (!ptr.unique());

ptr.reset();  // To eliminate the last reference

从技术上讲,如果指针的引用计数超过 1,则应该尝试调用 std::shared_ptr::reset,除非它达到 1。对此有什么想法吗?

【问题讨论】:

  • std::weak_ptr ?
  • 这绝对是XY problem究竟你想做什么,你认为你需要这样做?
  • shared_ptr中的“共享”是指“共享所有权”而不是“共享资源”。您的所有权并未真正共享,但只有一个所有者,其他所有者仅持有指针(又名 weak_ptr)。
  • @RezaHajianpour:那么你的代码是不连贯的。你说这个“引擎”应该单独负责销毁对象,但是这个get_model 函数明确与其他人分担该责任。你不能同时拥有它。修复你代码中的矛盾,应该没问题。
  • @RezaHajianpour 为什么不在引擎内部使用std::unique_ptr 来维护Model 对象的独占所有权,然后让get_model() 返回一个不转移/共享所有权的原始Model* 指针?

标签: c++ c++11 pointers c++17 smart-pointers


【解决方案1】:

这段代码没有任何意义。

一旦你重置ptr,它就不再管理对象了。如果ptr 是唯一的shared_ptr 共享所有权,那么您就完成了。如果不是……那么,您将无法访问所有其他人。在未参与的shared_ptr 上调用reset() 实际上是一个noop - 没有什么需要重置的。

想象一个简单的场景:

std::shared_ptr<int> a = std::make_shared<int>(42);
std::shared_ptr<int> b = a; // a and b are sharing ownership of an int

do {
    a.reset();
} while (!a.unique());

重置b 的唯一方法是重置b - 此代码只会重置a,它不可能到达b

另请注意,unique() 在 C++17 中已弃用,并在 C++20 中完全删除。但是即使你使用use_count(),一旦你使用a.reset()a.use_count() 将等于0,因为a 不再指向一个对象。

【讨论】:

  • 谢谢。那么引用计数是否静态保存在内存中?
  • @RezaHajianpour “静态保存”是什么意思?引用计数内存中。
  • 我的意思是它不是 std::shared_ptr 的对象实例的一部分?具体保存在哪里?
  • @RezaHajianpour 每个由shared_ptrs 管理的对象也有一个单独的控制块分配给它,每个shared_ptrweak_ptr 引用该对象。它包含计数器。
  • @RezaHajianpour 它不能是对象实例的一部分。想想它是如何工作的 - 当我在上面创建 b 时,a 的破坏无法释放对象。
【解决方案2】:

不,这是不可能的(或不可取的)。共享指针的意义在于,如果你有一个,你可以保证它指向的对象(如果有的话)不会从你下面消失,直到(至少)你完成它。 p>

调用ptr.reset() 只会将引用计数减少1 - 作为共享指针的引用。它永远不会影响来自共享您对象的其他共享指针的其他引用。

【讨论】:

    猜你喜欢
    • 2014-09-08
    • 2016-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多