Elimina la invocacion del destructor explicita. Deja que el objeto se destruya solo al morir el programa.
Exacto como bien te han explicado ahí no debes escribir:
perro1.~doggo();
Ya que el destructor de una clase se invoca automáticamente al terminar el programa. Además en los casos en que no usas memoria dinámica no es necesario definir el destructor ya que la clase proporciona uno por defecto (como ocurre con el constructor). En cambio si utilizas memoria dinámica, en el destructor tendrías que liberar esa memoria ya que sino el programa correrá aparentemente sin problemas pero estarás dejando memoria sin liberar.
¿Entonces si quieres aplicar el destructor explícitamente durante el programa? Muy sencillo, creas un método auxiliar con las instrucciones del destructor y en el destructor sólo llamas a ese método auxiliar. Así si quieres usarlo en otro punto del programa sólo deberás invocar al método auxiliar. Pero recuerda, si invocas el método auxiliar por ejemplo para liberar memoria dinámica, tendrás que volver a reservar memoria antes de llegar al final y de que se llame al destructor; sino estarás liberando dos veces la memoria y la segunda vez te producirá un error.
Doggo::miDestructor(){
// instrucciones del destructor
}
Doggo::~Doggo(){
miDestructor;
}
int main(){
Doggo perro1;
// otras instrucciones del programa
perro1.miDestructor();
// otras instrucciones del programa
return 0; // se llama automaticamente a ~Doggo()
}
Aunque estás empezando ya llegarás a trabajar con memoria dinámica por lo que ten presente esto. Ánimo.