Vous avez deux préoccupations, dont l'une est une conséquence de l'autre:
1) Vous ne devez autoriser aucune exception à échapper au destructeur. Si vous le faites, et si le destructeur est appelé dans le cadre du déroulement de Stack, alors l'exécution terminate()
votre programme. Ce n'est pas un comportement indéfini, mais c'est assez négatif.
Pour cette raison (et bien sûr parce que les destructeurs ne renvoient pas de valeur):
2) Il n'y a aucun moyen raisonnable pour votre destructeur d'indiquer le succès ou l'échec (signification "raisonnable", sans construire une sorte de système de rapport d'erreur distinct). Étant donné que l'utilisateur de votre classe pourrait vouloir savoir si la sauvegarde s'est produite ou non, de préférence avec une API raisonnable pour le faire, cela signifie que les destructeurs ne peuvent enregistrer que des données sur une base de "meilleur effort". Si la sauvegarde échoue, l'objet est toujours détruit, et donc probablement ses données sont perdues.
Il existe une stratégie pour de telles situations, utilisée par exemple par des flux de fichiers. Cela fonctionne comme ceci:
- avoir un
flush()
(ou dans votre cassave()
) Fonction qui enregistre les données - Appelez cette fonction à partir du destructeur si l'objet n'a pas déjà été enregistré / rincé (ou plus probablement: appelez-le inconditionnellement, mais demandez à la fonction elle-même de savoir s'il doit faire un travail réel ou non). Dans le cas des flux de fichiers, cela se produit via
close()
. Catchez toutes les exceptions qu'il peut lancer et ignorer les erreurs.
De cette façon, les utilisateurs qui ont besoin de savoir si la sauvegarde a réussi ou non save()
découvrir. Les utilisateurs qui ne se soucient pas (ou qui ne le dérangeraient pas de réussir si possible dans le cas qu'une exception est lancée et que l'objet est détruit dans le cadre du déroulement de la pile) peut laisser le destructeur essayer.
C'est-à-dire votre destructeur boîte Essayez de faire quelque chose qui pourrait échouer, comme un dernier effort, mais vous devez en outre fournir aux utilisateurs un moyen de faire la même chose "correctement", d'une manière qui les informe du succès ou de l'échec.
Et oui, cela signifie accidentellement que l'utilisation de flux sans les rincer et vérifier l'état du flux pour l'échec ne les utilise pas "correctement", car vous n'avez aucun moyen de savoir si les données ont jamais été écrites ou non. Mais il y a des situations où c'est assez bon, et dans le même genre de situation, il pourrait être assez bon pour que votre classe économise dans son destructeur.