Я реализовал простой ResourceManager - все было в порядке, пока я не попытался реализовать его деструктор для (экстренной) очистки (например, в случае фатального исключения). Я не смог найти ни одного способа сделать это:
Как освободить ресурсы от shared_ptr 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 не является технически (единоличный) владелец ресурсов? Это может быть недостатком дизайна, если это так, предложите альтернативу.
EDIT: в ответ на ответы, чтобы определить «диспетчер ресурсов». Я представляю себе авторитетный кеш-хранилище для ссылок на ресурсы, которые могут искать ресурсы (= нет дубликатов) и управляет их состоянием в памяти (in-memory, description -одно (= путь + тип) и освобождается), все вышеописанное максимально автоматизировано. (Там должны быть отдельные ResourceLoaders, но это не изменится на этот вопрос)
Лично я не вижу в этом хорошего дизайна. В чем смысл совместного владения, если кто-то может уничтожить подстилающий объект произвольно? Я не думаю, что это хорошая идея перевернуть концепцию совместного владения как это. Подумайте о том, чтобы вместо этого вернуть только ссылку, weak_ptr или * resource handle *, и пусть менеджер ресурсов сохраняет право собственности. – glampert
[Это] (http://scottbilas.com/publications/gem-resmgr/) также может быть вам полезен. – glampert
@ glampert хорошо, это статья 2000 года - она реализует собственные 'weak_ptr' с помощью дескрипторов, поскольку они не были частью std до C++ 11 (по крайней мере, для google sais). Это почти то же самое, что и раздавать 'weak_ptr' и' .lock() 'ing. Но это то, что я изначально пытался избежать - необходимость проверять ресурс перед каждым использованием. – wondra