gpt4 book ai didi

c++ - (shared_ptr + weak_ptr)兼容原始指针的设计

转载 作者:行者123 更新时间:2023-11-27 22:47:47 26 4
gpt4 key购买 nike

序言

在 C++11 中有 std::shared_ptr + std::weak_ptr 组合。尽管非常有用,但它有一个讨厌的问题:你 cannot easily construct shared_ptr from a raw pointer .由于这个缺陷,这种智能指针通常变得“流行”:人们开始完全避免原始指针和引用,并在整个代码中专门使用 shared_ptr 和 weak_ptr 智能指针。因为无法将原始引用传递给需要智能指针的函数。

另一方面,boost::intrusive_ptr。它等同于 std::shared_ptr 并且可以很容易地从原始指针构造,因为引用计数器包含在对象中。不幸的是,它没有 weak_ptr 伴侣,所以没有办法拥有非拥有的引用,您可以检查这些引用是否无效。事实上,有些人认为 weak companion for intrusive_ptr is impossible .

现在,有 std::enable_shared_from_thisembeds a weak_ptr直接进入你的类,这样你就可以从指向对象的指针构造 shared_ptr 。但是有一个小的限制(至少一个 shared_ptr 必须存在),它仍然不允许明显的语法:std::shared_ptr(pObject)

此外,还有一个 std::make_sharedallocates reference counters and the user's object in a single memory chunk .这与 intrusive_ptr 的概念非常接近,但是用户的对象可以独立于引用计数 block 被销毁。此外,这个概念有一个不可避免的缺点:只有当所有 weak_ptr-s 都消失时,整个内存块(可能很大)才会被释放。

问题

主要问题是:如何创建一对 shared_ptr/weak_ptr,这将同时具有 std::shared_ptr/std::weak_ptrboost::intrusive_ptr?

特别是:

  1. shared_ptr 模型共享对象的所有权,即对象在最后一个指向它的 shared_ptr 被销毁时被销毁。
  2. weak_ptr 不对对象的所有权建模,它可用于解决循环依赖问题。
  3. 可以检查 weak_ptr 是否有效:当存在指向该对象的 shared_ptr 时它是有效的。
  4. shared_ptr 可以从有效的 weak_ptr 构造。
  5. weak_ptr 可以从指向对象的有效原始指针构造。如果存在至少一个 weak_ptr 仍然指向该对象,则原始指针有效。从无效指针构造 weak_ptr 会导致未定义的行为。
  6. 整个智能指针系统应该像上面提到的现有系统一样对转换友好。

侵入式是可以的,即要求用户从给定的基类继承一次。当对象已经被销毁时保留对象的内存也是可以的。拥有线程安全性非常好(除非效率太低),但没有它的解决方案也很有趣。可以为每个对象分配多个内存块,但最好为每个对象分配一个内存块。

最佳答案

  • 点 1-4 和点 6 已经由 shared_ptr/weak_ptr 建模。

  • 第 5 点毫无意义。如果生命周期是共享的,则如果 weak_ptr 则没有有效对象存在但一个 shared_ptr才不是。任何原始指针都是无效指针。对象的生命周期已经结束。该对象已不复存在。

A weak_ptr不会使对象保持事件状态,它会使控制 block 保持事件状态。 shared_ptr保持控制 block 和受控对象都处于事件状态。

如果您不想通过将控制 block 与受控对象组合来“浪费”内存,请不要调用 make_shared .

如果你不想shared_ptr<X>要病毒式地传递到函数中,请不要传递它。传递对 X 的引用或常量引用.你只需要提shared_ptr如果您打算在函数中管理生命周期,请在参数列表中。如果您只想对 shared_ptr 指向的内容执行操作,请传递 *p*p.get()并接受一个 [const] 引用。

关于c++ - (shared_ptr + weak_ptr)兼容原始指针的设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41262492/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com