1

我实现了一个简单的 ResourceManager - 一切都很好,直到我尝试实现它的析构函数以进行(紧急)清理(例如在致命异常的情况下)。我无法找到一种方法来做到这一点:

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_);
    }
};

显然,我必须遍历所有活动资源......但是如果 ResourceManager 在技术上不是资源的(唯一)所有者,我该如何释放它们?这可能是设计缺陷,如果是这种情况,请提出替代方案。

编辑:为了响应答案,定义“资源管理器”我想象权威缓存 - 存储对资源的引用,可以查找资源(=无重复)并管理它们在内存中的状态(内存中,仅描述(=路径+type) 和 freed),所有这些都尽可能自动化。(应该有单独的 ResourceLoaders,但这对于这个问题并没有太大变化)

4

2 回答 2

2

要提出替代方案,我们需要知道您的资源经理应该有什么目的。

  1. 您是否希望它充当“资源集合”,即保持资源活动直到它们被明确释放?
  2. 或者您是否希望它成为“资源缓存”,让资源保持活动状态,直到它决定应该释放一些资源以释放内存?
  3. 还是您真的希望它不保留任何资源,而只是保留可能被其他东西保留的资源列表?

请记住,shared_ptrC++ 中的 s 不像 GC 那样工作。即,如果您销毁/重置最后shared_ptr一个对象,该对象将立即被删除,即使它有weak_ptrs。

所以方法(1)和(2)很有意义。(3) 然而,这是你目前所拥有的,只是很少有意义(如果有的话)。

于 2015-01-30T00:01:36.887 回答
2

所以,你的代码在这里并没有做很多事情来阐明你的整体设计,但是......

实施时,您的资源管理器似乎只有指向资源的弱指针。这表明它不对实际资源本身的生命周期负责,因此不应在其析构函数中清理这些资源。

如果您希望资源管理器成为资源数据的权威所有者,您将需要更改其设计/实现。例如,您可以让它将shared_ptrs 存储到资源本身,并且只将weak_ptrs 传递给客户端。或者只是存储unique_ptrs 并将裸指针传递给客户端代码。

但正如所写,您不需要(而且真的不能)做任何事情来清理~ResourceManager().

于 2015-01-29T22:57:25.730 回答