4

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

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

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

不过我的问题是,您将如何与其他系统共享向量的内容?你不能只传递 unique_ptr,因为这会改变所有权(由于它的 unique_ptr),我想要资源管理器中的唯一所有权。

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

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 

虽然感觉有点花哨,但肯定有更好,更直接的解决方案吗?

4

2 回答 2

12

有一个简单的解决方案。

传递vec[n].get()——原始指针。只要您不存放它们,并始终从所有者那里取回它们,并且所有者在您使用它们时不破坏它们,您就安全了。

如果您不愿意遵循那种级别的纪律,那么您需要的是 a std::shared_ptrin vector,并传递和存储std::weak_ptrs。s将在最后一个消失weak_ptr时自动失效(并且根据策略,唯一持久的就是 owning 中的那个)。shared_ptrshared_ptrvector

这有一个额外的好处,如果你正在处理一个元素并且vector清除它本身,你就不会出现段错误。您访问 a weak_ptrby .lock(),它返回 a shared_ptr,在其生命周期内保证原始指针是好的。

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

于 2013-07-19T18:59:26.483 回答
0

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

于 2013-07-19T20:11:29.977 回答