处理容器中的unique_ptr

Dealing with unique_ptr in containers

本文关键字:unique ptr 处理      更新时间:2023-10-16

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

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

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

我的问题是,您将如何与其他系统共享矢量的内容?你不能只是传递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 

不过感觉有点噱头,肯定有更好、更直接的解决方案吗?

有一个简单的解决方案。

传递vec[n].get() -- 原始指针。 只要你不储存它们,并且总是从主人那里拿回它们,并且主人在你使用它们时不破坏它们,你就是安全的。

如果你不愿意遵循这种程度的纪律,你需要的是vector中的std::shared_ptr,并传递和存储std::weak_ptr。 当最后一个shared_ptr消失时,weak_ptr s 将自动失效(根据策略,唯一的持久shared_ptr是拥有vector中的那个(。

这有一个额外的优势,如果你正在对一个元素进行工作,并且vector会自行清除,你就不会出现段错误。 你通过 .lock() 访问一个weak_ptr,它返回一个shared_ptr,在其生命周期内,原始指针保证是好的。

缺点是这增加了成本,好处是它允许弱共享所有权和延迟无效通知。

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