En tu código hay un problema y es que se invoca dos veces el destructor:
- La primera vez se corresponde con la llamada explícita que has añadido al main
- La segunda cuando finaliza el programa (la ejecución abandona la instrucción
main
y ello provoca que se llame al destructor de todos los objetos cuyo ámbito sea la propia función main
).
¿Y por qué llamar dos veces al destructor provoca el fallo del programa?
Puede ser algo tan tonto con un borrado doble:
Es bastante probable que la clase sf::SoundBuffer
haga uso de memoria dinámica, luego no sería dificil encontrar una implementación similar a la mostrada en el ejemplo siguiente:
class Test
{
int* ptr;
public:
Test()
: ptr{new int(5)}
{ }
~Test()
{
delete ptr;
}
};
Aquí tienes una clase de lo más tonta que solo implementa un constructor y un destructor... Y al usarla correctamente no da ningún problema:
int main()
{
Test t;
}
Sin embargo basta con llamar explícitamente al destructor para que esa clase tan simplona empiece a dar problemas:
int main()
{
Test t;
t.~Test();
}
Lo que sucede aquí es que la llamada explícita al destructor libera la memoria asignada a ptr
y, posteriormente, se ejecuta un segundo delete
sobre el mismo puntero y esto provoca un comportamiento indefinido que, generalmente, se traduce en que el sistema operativo mata tu aplicación para que no corrompa la memoria de otros procesos.
El error se puede subsanar facilmente haciendo que ptr
apunte a 0
después del delete:
~Test()
{
delete ptr;
ptr = nullptr; /* o, si no compilas con C++11, tambien vale 0 o NULL */
}
Ahora el error ya no se reproducirá porque un delete de un puntero que apunta a 0 no tiene consecuencias... sin embargo siempre será más limpio y sano para tu código evitar hacer cosas raras y dejar al compilador la responsabilidad de ejecutar las funciones especiales (constructores y destructores generalmente).
Pero claro, es mucho más sencillo no hacer cosas raras y dejar