33

次のように宣言されたマップがあります

std::map<std::string, Texture*> textureMap;

これは、テクスチャ ファイルへのパスを実際のテクスチャにペアリングするために使用します。これにより、個々のスプライトに対して同じテクスチャを何度もロードすることなく、パスでテクスチャを参照できます。どうすればよいかわからないのは、ResourceManager クラス (マップがある場所) のデストラクタでテクスチャを適切に破棄することです。

次のようなイテレータでループを使用することを考えました。

ResourceManager::~ResourceManager()
{
    for(std::map<std::string, Texture*>::iterator itr = textureMap.begin(); itr != textureMap.end(); itr++)
    {
        delete (*itr);
    }
}

しかし、それは機能しません.deleteにはポインタが必要です. かなり遅いので、明らかな何かが欠けているだけかもしれませんが、就寝前にこれを機能させたかったのです。それで、私はこれに近づいていますか、それとも完全に間違った方向に進んでいますか?

4

3 に答える 3

49

サンプル コードに関する限り、ループ内でこれを行う必要があります。

delete itr->second;

マップには 2 つの要素があり、2 番目の要素を削除する必要があります。あなたの場合、itr->firstは でstd::stringありitr->secondTexture*です。

特定のエントリを削除する必要がある場合は、次のようにすることができます。

std::map<std::string, Texture*>::iterator itr = textureMap.find("some/path.png");
if (itr != textureMap.end())
{
    // found it - delete it
    delete itr->second;
    textureMap.erase(itr);
}

エントリがマップに存在することを確認する必要があります。そうしないと、テクスチャ ポインタを削除しようとしたときに例外が発生する可能性があります。

別の方法std::shared_ptrとして、生のポインターの代わりに使用することもできます。その場合、マップからアイテムを削除するためのより単純な構文を使用し、std::shared_ptr必要に応じて基になるオブジェクトの削除を処理させることができます。erase()そうすれば、次のようにキー引数を使用できます。

// map using shared_ptr
std::map<std::string, std::shared_ptr<Texture>> textureMap;

// ... delete an entry ...
textureMap.erase("some/path.png");

これにより、次の 2 つのことが行われます。

  • エントリが存在する場合は、マップからエントリを削除します
  • への他の参照がない場合Texture*、オブジェクトは削除されます

使用std::shared_ptrするには、最新の C++11 コンパイラまたはBoostが必要です。

于 2013-11-14T05:54:10.190 に答える
0

仕事に適したツールを使用していません。

ポインタはデータを「所有」してはなりません。

boost::ptr_map<std::string, Texture>代わりに使用してください。

于 2013-11-14T08:09:32.327 に答える