次のように宣言されたマップがあります
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 itr->second;
_
マップには2つの要素があり、2番目の要素を削除する必要があります。あなたの場合、_itr->first
_は_std::string
_であり、_itr->second
_は_Texture*
_です。
特定のエントリを削除する必要がある場合は、次のようにすることができます。
_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
_を使用し、couldより簡単な構文を使用してマップからアイテムを削除し、必要に応じて、_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 が必要です。
答えはループの問題を完全には解決しませんでした。少なくともCoverty(TM)では、ループ内でイテレーターを消去することはできませんが、それを使用してループを続行します。とにかく、メモリを削除した後、マップ上でclear()を呼び出すと残りの処理が行われます。
ResourceManager::~ResourceManager()
{
for(std::map<std::string, Texture*>::iterator itr = textureMap.begin(); itr != textureMap.end(); itr++)
{
delete (itr->second);
}
textureMap.clear();
}