C++ 处理容器中的唯一\u ptr
我有一个独特的向量,指向模型、网格等,如下所示:C++ 处理容器中的唯一\u ptr,c++,c++11,smart-pointers,unique-ptr,C++,C++11,Smart Pointers,Unique Ptr,我有一个独特的向量,指向模型、网格等,如下所示: std::vector<std::unique_ptr<Model>> mLoadedModels; std::vector mloaddemdodels; 我选择unique_ptr是因为它会在向量析构函数上自动释放数据,也因为稍后如果我需要重新加载所有模型(由于OpenGL上下文的破坏/创建),我可以在我的资源管理器reset()中内部将其指向一个新的模型实例,而不会影响系统的其余部分 但我的问题是,如何与其他系统
std::vector<std::unique_ptr<Model>> mLoadedModels;
std::vector mloaddemdodels;
我选择unique_ptr是因为它会在向量析构函数上自动释放数据,也因为稍后如果我需要重新加载所有模型(由于OpenGL上下文的破坏/创建),我可以在我的资源管理器reset()中内部将其指向一个新的模型实例,而不会影响系统的其余部分
但我的问题是,如何与其他系统共享向量的内容?您不能只传递唯一的\u ptr,因为这会改变所有权(由于其唯一的\u 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
模板
结构句柄
{
句柄(std::unique_ptr&resource):mResource(resource)
{
}
运算符*(){return mResource.get();}
常量T&运算符*()常量{return mResource.get();}
T*运算符->(){return mResource.get();}
常量T*运算符->()常量{return mResource.get();}
私人:
std::独特的ptr和MRE资源;
};
typedef句柄模型ptr;
modelptrgetmodel(const std::string和modelName);
//例如:
ModelPtr monkey=GetModel(“monkey”);
猴子->舞蹈();
//重新加载资源,然后取消对新模型实例的引用
虽然这感觉有点噱头,但肯定有更好、更直接的解决方案吗?有一个简单的解决方案 传递
vec[n].get()
——原始指针。只要你不储存它们,并且总是从所有者那里取回它们,并且所有者在你使用它们时不销毁它们,你就安全了
如果您不愿意遵守这一级别的规程,您需要的是std::shared_ptr
在vector
中,传递并存储std::weak_ptr
s。当最后一个共享的
消失时,弱的
将自动失效(根据策略,唯一持久的共享的
是拥有的向量中的一个
这有一个附加的优点,如果你在一个元素上工作,而向量 >清除它自己,你就不会出错。您可以通过.lock()
访问弱\u ptr
,它返回一个共享的\u ptr
,在其生存期内,原始指针保证是良好的
缺点是这会增加成本,优点是它允许弱共享所有权和延迟无效通知。使用普通的std::vector
并向各个元素分发原始指针。除非您需要动态多态性或期望对模型的引用超过向量的寿命,否则不需要将其变得更复杂。如果您需要共享所有权,请使用shared\u ptr
。然后,您可以将弱ptr
s分发给观察者。句柄
显然应该命名为唯一ptr
。别开玩笑了,当向量调整大小时,你的句柄将无效。分发原始模型*
有什么不对?@Casey真的,它应该是共享的独特的ptr
来处理生命问题(我的孩子)。@Yakk我喜欢使用共享的独特的ptr*
来覆盖我所有的基础。不过我确实需要存储它们,例如,我的模型存储一个MeshPtr和一个MaterialPtr,等等。我想让它也像指针一样透明,使用弱ptr,每次你想访问资源时都必须执行lock(),对吗?先传递一个vec,然后是一个索引号,用句柄“`@KaiserJohaan”这样的结构包装,很少有理由将引用存储在持久对象中。第二,如果指针在任何一点上都无效,“作为指针透明”是不好的.lock()
定义了一个作用域,在该作用域中指针不能无效且可以安全使用。如果你能证明所讨论的指针只会在某些点被销毁,那就太过分了……没有好的替代方法可以避免每次访问它时都必须执行.lock()。@kaiserjohaan sure:制定合理的生存期和访问规则。拥有它的人提供了它,而销毁发生在与非拥有指针生命周期不重叠的已知时间。如果std::vector
调整大小,则指向Model
的指针将失效,因此它们无法在任何可能修改std::vector
长度的代码上持久存在@Yakk-Ah-yes,这太容易忘记了。现在,根据容器的操作方式,std::deque
可能是合适的,但可能std::unique\u ptr
/get
解决方案是最好的。