采用 unique_ptr 的元素集合,但将它们存储为 shared_ptr 以提供作为 weak_ptr 的访问

Collection of elements that takes unique_ptr, but stores them as shared_ptr to provide access as weak_ptr

以下是否被视为 bad/good 做法?为什么?

class Scene
{
    public:
        std::weak_ptr<Node>                 AddChild(std::unique_ptr<Node> node);
        std::unique_ptr<Node>               DetachChild(std::string name);

    private:
        std::vector<std::shared_ptr<Node>>  mNodes;
};

想法是确保 Scene 是其子项的唯一所有者,并在向该场景添加 Node 时强制转移所有权。但是,客户端应该有一种方法可以访问存储在场景中的节点(无需通过 name/id 不断查找)。

典型的例子是这样的:

  1. 您创建了一个 UI window(场景)
  2. 你给它添加了几个文本标签(节点)
  3. 您想保存指向这些标签的指针,以便以后修改文本。

替代方案也可以使用 unique_ptr 添加,但 return raw pointer,但是文本可以在不同的 类 中更新,并且应该始终检查标签存在(例如,可以有一个 运行 Tween 函数更新您在 "Fire and forget" 模式下触发的循环中的文本,只是想确保它不会访问悬挂指针(想想 cocos2d 个动作)即使检查只是意味着捕捉和断言)。

由于 shared_ptr 的性质,您想要的是不可能的。 unique_ptr 允许您在不删除指针的情况下提取指针,而 shared_ptr 则不允许。

由于线程问题,您想要的也不是好的做法。即使您实现了自己的智能指针,它完全符合您的要求,您如何使用它?用户可以锁定其中一个句柄,然后在另一个线程中将内部智能指针转换为 unique_ptr。这是如何运作的?你所拥有的是两段代码,它们在概念上都拥有该对象,但只有其中一段代码控制着它的生命周期。

除非你禁止线程,否则这在 Murphy 的领域中非常重要。

像这样的事情正是为什么shared_ptr不能放弃它对指针的所有权。

Basically I need unique_ptr that can return a pointer that will become null as soon as the original unique_ptr gets destroyed.

这正是 weak_ptr 不提供对内部指针的直接访问的原因。你必须锁定它,这保证你可以访问内存,只要你保持shared_ptr

此编码模式可防止您的想法所造成的数据竞争。

shared_ptr 是由一些非常聪明的人长期工作设计的。忽视它的智慧,后果自负。