C++ 如何从shared_ptr ResourceManager释放资源
我实现了一个简单的ResourceManager——在我尝试实现它的析构函数进行(紧急)清理(例如在发生致命异常的情况下)之前,一切都很好。我找不到一种方法来做这件事:C++ 如何从shared_ptr ResourceManager释放资源,c++,resource-management,memory,C++,Resource Management,Memory,我实现了一个简单的ResourceManager——在我尝试实现它的析构函数进行(紧急)清理(例如在发生致命异常的情况下)之前,一切都很好。我找不到一种方法来做这件事: template<typename T> class ResourceManager { public: std::unordered_map<std::string, std::weak_ptr<T> > resource_map; std::shared_p
template<typename T>
class ResourceManager
{
public:
std::unordered_map<std::string, std::weak_ptr<T> > resource_map;
std::shared_ptr<T> getResource(std::string name)
{
std::shared_ptr<T> res = resource_map[name].lock();
if(!res)
{
res = std::shared_ptr<T>(new T(this, name));
resource_map[name] = res;
}
return std::move(res);
}
void Release(std::string name)
{
resource_map.erase(name);
};
~ResourceManager(void) { /* ???? */}
};
class Texture
{
private:
ResourceManager<Texture> * manager_;
std::string name_;
public:
Texture(ResourceManager<Texture> * manager, std::string& name)
: manager_(manager), name_(name) { }
~Texture(void){
manager_->Release(name_);
}
};
模板
班级资源经理
{
公众:
std::无序地图资源地图;
std::shared_ptr getResource(std::string name)
{
std::shared_ptr res=resource_map[name].lock();
如果(!res)
{
res=std::shared_ptr(新的T(这个,名字));
资源映射[名称]=res;
}
返回std::移动(res);
}
无效释放(标准::字符串名称)
{
资源映射擦除(名称);
};
~ResourceManager(无效){/*?????*/}
};
类纹理
{
私人:
资源经理*经理*;
std::字符串名称;
公众:
纹理(ResourceManager*管理器,标准::字符串和名称)
:经理,姓名{}
~Texture(void){
经理->发布(姓名);
}
};
显然,我必须迭代所有活动资源……但是如果ResourceManager不是资源的技术(唯一)所有者,我如何释放它们呢?这可能是设计上的缺陷,如果是这种情况,请建议替代方案。编辑:为了响应回答,要定义“资源管理器”,我设想使用权威缓存存储对资源的引用,这些资源可以查找资源(=无重复项)并管理其在内存中的状态(在内存中,仅描述(=路径+类型)和释放),所有这些都尽可能自动化。(应该有单独的ResourceLoader,但这对这个问题没有太大的改变)因此,您的代码在这里并没有对您的总体设计做太多说明,但是 在实现时,资源管理器似乎只有指向资源的弱指针。这表明它不负责实际资源本身的生命周期,因此不应该在其析构函数中清理这些资源 如果希望资源管理器成为资源数据的权威所有者,则需要更改其设计/实现。例如,您可以让它将
shared_ptr
s存储到资源本身,而只将weak_ptr
s发送到客户端。或者只需存储unique_ptr
s并向客户机代码发送裸指针
但是,正如本文所述,您不需要(实际上也不能)做任何事情来清理
~ResourceManager()
中的资源,因此,您的代码在这里没有做很多事情来说明您的总体设计,但是
在实现时,资源管理器似乎只有指向资源的弱指针。这表明它不负责实际资源本身的生命周期,因此不应该在其析构函数中清理这些资源
如果希望资源管理器成为资源数据的权威所有者,则需要更改其设计/实现。例如,您可以让它将shared_ptr
s存储到资源本身,而只将weak_ptr
s发送到客户端。或者只需存储unique_ptr
s并向客户机代码发送裸指针
但正如本文所述,您不需要(实际上也不能)做任何事情来清理
~ResourceManager()
中的资源。要提出替代方案,我们需要知道您的资源管理器应该有什么用途
共享\u ptr
,则该对象将立即被删除,即使该对象存在弱\u ptr
s
因此,方法(1)和(2)非常有意义。(3) 然而,这正是您目前拥有的,只有很少有意义(如果有的话)。要提出替代方案,我们需要知道您的资源经理应该有什么目的
共享\u ptr
,则该对象将立即被删除,即使该对象存在弱\u ptr
s
因此,方法(1)和(2)非常有意义。(3) 然而,这是你目前拥有的,只有很少有意义(如果有的话)。好吧,如果我分发
弱\u ptr
,每次我决定使用它时,我都必须检查资源是否在内存中,不是吗?这能以某种方式自动/同步吗?这样我就可以保持分发shared\u ptr
s的优势了?(=不需要每次使用都检查,并且知道资源有多少活动用户?)是的,客户端必须锁定()弱指针。如果你想让客户端知道他们的指针是否死了,并使用集中所有权模型而不是共享所有权模型,那就真的没有办法避免检查。好吧,如果我分发弱\u ptr
,每次我决定使用它时,我都必须检查资源是否在内存中,不是吗?能以这样的方式自动/同步吗