J'ai une carte déclarée comme
std::map<std::string, Texture*> textureMap;
que j'utilise pour associer le chemin d'un fichier de texture à la texture réelle afin que je puisse référencer la texture par le chemin sans charger la même texture plusieurs fois pour des sprites individuels. Ce que je ne sais pas faire, c'est détruire correctement les textures dans le destructeur de la classe ResourceManager (où se trouve la carte).
J'ai pensé à utiliser une boucle avec un itérateur comme celui-ci:
ResourceManager::~ResourceManager()
{
for(std::map<std::string, Texture*>::iterator itr = textureMap.begin(); itr != textureMap.end(); itr++)
{
delete (*itr);
}
}
Mais cela ne fonctionne pas, il dit que supprimer attend un pointeur. Il est assez tard, donc je manque probablement quelque chose d'évident, mais je voulais que cela fonctionne avant de se coucher. Alors suis-je proche ou suis-je totalement dans la mauvaise direction avec ça?
En ce qui concerne votre exemple de code, vous devez le faire dans la boucle:
delete itr->second;
La carte comporte deux éléments et vous devez supprimer le second. Dans votre cas, itr->first
Est un std::string
Et itr->second
Est un Texture*
.
Si vous devez supprimer une entrée particulière, vous pouvez faire quelque chose comme ceci:
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);
}
Vous devez vous assurer que l'entrée existe dans la carte, sinon vous risquez d'obtenir une exception lorsque vous essayez de supprimer le pointeur de texture.
Une alternative pourrait être d'utiliser std::shared_ptr
Au lieu d'un pointeur brut, alors vous pourriez utiliser une syntaxe plus simple pour supprimer un élément de la carte et laissez le std::shared_ptr
gérer la suppression de l'objet sous-jacent lorsque cela est approprié. De cette façon, vous pouvez utiliser erase()
avec un argument clé, comme ceci:
// map using shared_ptr
std::map<std::string, std::shared_ptr<Texture>> textureMap;
// ... delete an entry ...
textureMap.erase("some/path.png");
Cela fera deux choses:
Texture*
, L'objet sera suppriméPour utiliser std::shared_ptr
, Vous aurez besoin d'un compilateur C++ 11 récent ou Boost .
La réponse n'a pas entièrement résolu le problème de la boucle. Au moins, Coverty (TM) ne permet pas d'effacer l'itérateur dans la boucle et de l'utiliser quand même pour continuer la boucle. Quoi qu'il en soit, après avoir supprimé la mémoire, appeler clear () sur la carte devrait faire le reste:
ResourceManager::~ResourceManager()
{
for(std::map<std::string, Texture*>::iterator itr = textureMap.begin(); itr != textureMap.end(); itr++)
{
delete (itr->second);
}
textureMap.clear();
}
Vous n'utilisez pas le bon outil pour le travail.
Utilisation boost::ptr_map<std::string, Texture>
à la place.