So I was able to resolve this warning for sfml::music by using "GameData->assets.music.~SoundSource();" before I exited the window. However I am not sure that is proper.
I'm sure it's
not proper.
In fact, calling destructors manually is undefined behavior (UB), if they are called again automatically.
void AssetManager::RemoveSoundBuffer(const string name) {
if (this->_soundBuffers.find(name) != _soundBuffers.end())
_soundBuffers.erase(name);
}
I don't know what data structure
_soundBuffers is -- but if it's a
std::vector or
std::deque, erasing one element will invalidate pointers to the erased element
and all subsequent elements. Since every
sf::Sound stores a pointer to a
sf::SoundBuffer, you may trigger UB here as well, due to dangling pointers. A
std::list or
std::map would not have this problem, they are
stable data structures.
It's relatively simple to get sound lifetimes right, you need to consider the following rules:
- Use automatic memory for all the objects (STL containers and smart pointers). Do not use new/delete, manual destructor calls or other unnecessarily low-level techniques.
- Every sf::SoundBuffer must outlive all the sf::Sound instances that refer to it.
- A sf::SoundBuffer must not be moved/copied while it's in use (e.g. by erasing from a container).
- Don't allocate any SFML objects globally (this obviously includes other objects that are global and contain SFML objects). Initialization and destruction order of global variables is a big mess in C++.
In case you want a readily available solution for managing resources like
sf::SoundBuffer, you might be interested in my library Thor (here's a
tutorial which shows some examples).