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

标签 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. 您想保存指向这些标签的指针,以便以后修改文本。

也可以使用 unique_ptr 添加但返回 raw pointer,但是文本可以在不同的类中更新,并且应该始终检查标签是否存在(例如,可以有一个正在运行的 Tween 函数更新您在“即发即弃”模式下触发的循环中的文本,只是想确保它不会访问悬挂指针(想想 cocos2d actions) 即使检查只是意味着捕获和断言)。

最佳答案

由于 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 是由一些非常聪明的人长期工作设计的。忽视它的智慧,后果自负。

关于c++ - 采用 unique_ptr 的元素集合,但将它们存储为 shared_ptr 以提供作为 weak_ptr 的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34277581/

相关文章:

c++ - 在标准输出中执行打印导致随机分配数组中的值

c++ - Windows 和 native android 之间 std::shared_ptr 的区别

c++ - 确保全局记录器对象的生命周期比其他全局对象长

c++ - 带有 std::shared_ptr 的视觉泄漏检测器

c++ - CLion 编译时卡住

c++ - 使用 C++ 从系统注册表中检索 ActiveX classID

c++ - std::shared_ptr 初始化:make_shared<Foo>() 与 shared_ptr<T>(new Foo)

C++ 内存映射文件数据预取

c++ - 检查值是否已经存在于 multimap C++ 中

c++11 - 获取最接近 double std::vector 中的值的项目