Как освободить ресурсы из shared_ptr ResourceManager

Я реализовал простой 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 не является технически (единственным) владельцем ресурсов? Это может быть недостатком дизайна, если это так, пожалуйста, предложите альтернативу.

РЕДАКТИРОВАТЬ: в ответ на ответы для определения «менеджера ресурсов» я представляю себе авторитетный кеш — хранилище для ссылок на ресурсы, которые могут искать ресурсы (= не дублировать) и управлять их состоянием в памяти (в памяти, только для описания (= путь + тип) ) и освобожден), все вышеизложенное максимально автоматизировано. (должны быть отдельные ResourceLoaders, но это не сильно изменится для этого вопроса)

1

Решение

Итак, ваш код не делает много для освещения вашего общего дизайна, здесь, но

При реализации ваш менеджер ресурсов, кажется, имеет только слабые указатели на ресурсы. Это указывает на то, что он не отвечает за время жизни самих реальных ресурсов и, следовательно, не должен очищать эти ресурсы в своем деструкторе.

если ты хочу Менеджер ресурсов, чтобы быть официальным владельцем данных ресурса, вы захотите изменить его дизайн / реализацию. Например, вы можете иметь его в магазине shared_ptrS к самим ресурсам, и только потерять сознание weak_ptrс клиентами. Или просто хранить unique_ptrs и раздать голые указатели на код клиента.

Но, как написано, вам не нужно (и не можете) ничего сделать, чтобы очистить ресурсы в ~ResourceManager(),

2

Другие решения

Чтобы предложить альтернативы, нам нужно знать, для чего предназначается ваш менеджер ресурсов.

  1. Хотите ли вы, чтобы он функционировал как «коллекция ресурсов», то есть поддерживал ресурсы до тех пор, пока они не были явно освобождены?
  2. Или вы хотите, чтобы это был «кэш ресурсов», сохраняющий ресурсы живыми до тех пор, пока он не решит, что некоторые из них должны быть освобождены для освобождения памяти?
  3. Или вы действительно хотите, чтобы он НЕ поддерживал какие-либо ресурсы, а просто поддерживал список ресурсов, которые возможно поддерживаются чем-то другим?

Помни что shared_ptrs в C ++ не работают как GC. То есть если вы уничтожите / сбросить последний shared_ptr объекту этот объект будет удален немедленно, даже если есть weak_ptrс этим.

Таким образом, подходы (1) и (2) могут иметь много смысла. (3) однако, то, что у вас есть в настоящее время, имеет смысл только очень редко (если вообще имеет смысл).

2

По вопросам рекламы [email protected]