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

时间:2015-12-14 22:12:24

标签: c++ c++11 shared-ptr unique-ptr weak-ptr

以下是否被视为不良/良好做法?为什么呢?

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时转移所有权。但是,客户端应该有一种方法可以访问存储在场景中的节点(无需经常按名称/ ID查找)。

典型的例子是:

  1. 您有一个创建的UI窗口(场景)
  2. 您可以为其添加多个文本标签(节点)
  3. 您希望保存指向这些标签的指针,以便稍后您可以修改文本。
  4. 替代方案也是使用unique_ptr添加但返回raw pointer,但是文本可以在不同的类中更新,并且应该始终检查标签是否存在(例如,可以运行Tween函数更新循环中的文本,在“Fire and forget”模式下触发,只是想确保它不会访问悬空指针(想想cocos2d动作)即使只是检查意味着只是捕捉和断言)。

1 个答案:

答案 0 :(得分:4)

由于shared_ptr的性质,您无法获得所需内容。虽然unique_ptr允许您在不删除指针的情况下提取指针,但shared_ptr却没有删除指针。

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

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

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

  

基本上我需要unique_ptr,它可以返回一个指针,一旦原始unique_ptr被破坏就会变为空。

这正是weak_ptr无法直接访问内部指针的原因。你必须锁定它,这保证只要你保留shared_ptr就可以访问内存。

这种编码模式可以防止您的想法会产生确切类型的数据争用。

shared_ptr是由一些非常聪明的人在很长一段时间内设计的。在你自己的危险中忽视它的智慧。