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

したがって、ここでは、コードは全体的なデザインを明らかにするために多くのことを行っていません...

実装すると、リソース マネージャーはリソースへの弱いポインターしかないように見えます。これは、実際のリソース自体の有効期間に責任がないことを示しているため、デストラクタでそれらのリソースをクリーンアップするべきではありません。

リソース マネージャーをリソース データの権限のある所有者にしたい場合は、その設計/実装を変更する必要があります。たとえば、 をshared_ptrリソース自体に格納し、 をクライアントに渡すだけにすることができweak_ptrます。または、単にunique_ptrs を格納し、クライアント コードへのベア ポインターを渡します。

しかし、書かれているように、 のリソースをクリーンアップするために何もする必要はありません (実際にはできません) ~ResourceManager()

于 2015-01-29T22:57:25.730 に答える