处理容器中的unique_ptr

时间:2013-07-19 18:51:03

标签: c++ c++11 smart-pointers unique-ptr

我有一个unique_ptrs向量,它指向模型,网格等,如下所示:

std::vector<std::unique_ptr<Model>> mLoadedModels;

我选择unique_ptr因为它会自动释放向量析构函数上的数据,并且因为稍后我需要重新加载所有模型(由于OpenGL上下文拆除/创建)我可以在内部资源管理器重置()并使其指向一个新的Model实例,它不会影响系统的其余部分。

我的问题是,你如何与其他系统分享载体的内容?你不能只传递unique_ptr,因为这会改变所有权(由于其unique_ptr),我想在rersource管理器中拥有唯一的所有权。

我想出的解决方案如下,将访问包装在以下结构中:

template<typename T>
struct Handle
{
    Handle(std::unique_ptr<T>& resource) : mResource(resource)
    {
    }

    T& operator*()                  { return mResource.get(); }
    const T& operator*() const      { return mResource.get(); }
    T* operator->()                 { return mResource.get(); }
    const T* operator->() const     { return mResource.get(); }


private:
    std::unique_ptr<T>& mResource;
};

typedef Handle<Model> ModelPtr;

ModelPtr GetModel(const std::string& modelName);

// example:
ModelPtr monkey = GetModel("Monkey");
monkey->dance();

// reload resources, and then monkey dereferences to the new Model instance 

虽然感觉有点噱头,但这肯定是一个更好,更直接的解决方案吗?

2 个答案:

答案 0 :(得分:10)

有一个简单的解决方案。

传递vec[n].get() - 原始指针。只要您不存储它们,并且始终从所有者那里取回它们,并且所有者在您使用它们时不会销毁它们,那么您就是安全的。

如果您不愿意遵循该级别的纪律,您需要的是std::shared_ptr中的vector,并传递并存储std::weak_ptr。当weak_ptr消失时,shared_ptr会自动失效(根据政策,唯一的持久shared_ptr是拥有vector中的那个。)

这具有额外的优势,如果您正在处理元素并且vector自行清除,则不会出现段错误。您访问weak_ptr .lock(),返回shared_ptr,在其生命周期内原始指针保证良好。

缺点是这会增加成本,其优点在于它允许弱共享所有权和懒惰的无效通知。

答案 1 :(得分:0)

使用普通std::vector <Model>并分发各个元素的原始指针。除非你需要动态多态或期望对模型的引用比向量更长,否则你不应该让它变得更复杂。