dans Delphi 5, j'ai actuellement écrit le code qui appelle gratuit code> sur plusieurs variables dans un bloc
enfin code>, par exemple
...
finally
a.Free;
b.Free;
c.Free;
end;
5 Réponses :
dépend de ce qui se passe dans le destructeur. P>
Totalement correct, j'ai supprimé mon mauvais anser. N'a pas pris en compte les destructeurs. C'est pourquoi les destructeurs ne doivent pas lancer d'exceptions.
bien sûr libre peut émettre des exceptions - alors oui, vous allez étanche de la mémoire dans votre code si A.Free émet une exception, B.Free et C.Free ne sera pas appelée.
La question est, voulez-vous Pour gérer les exceptions ou les laisser arriver? Son dépend de ce que votre code va être pour, d'autres devs vont l'utiliser (par exemple). Pour éviter toute fuite de mémoire, vous devez nicher les sections Essayy..Finalement; P>
a:=tobject.create; try b:=tobject.create; try c:=tobject.create; ... finally c.free; end; finally b.free; end; a.free;
Votre a.free; code> est en dehors de tout
Essayez code> ..
enfin code>, et vous essayez de libérer
B code> si < Code> B: = tobject.create; code> soulève une exception (même avec
C code>).
En outre, si c.free code> soulève une exception, vous avez toujours une fuite car vous n'avez pas réellement libéré
c code>.
Son déblable que c'est un bon style de codage de toute façon - mais j'ai dit que vous devriez probablement essayer. Je faisais seulement démontrer comment vous pourriez le faire :-)
Dans votre exemple, vous devez définitivement envelopper le a.free; code> dans un
essayer code> ..
enfin code> aussi. Si vous êtes absolument sûr à 100% duquel le code ne peut jamais soulever une exception, vous n'en avez pas besoin, mais vous n'avez alors besoin d'aucun des
essayer code> ..
enfin code> s que vous avez inclus.
Si votre fichier A.Free augmente une exception, a (en fonction de la quantité que le destructeur a libéré des champs d'objets d'A), les objets B et C seront des fuites car l'exécution sera interrompue. Quoi qu'il en soit, quelque chose ne va pas dans votre destructeur, s'il augmente une erreur. Donc, vous devriez protéger le code avec des blocs tressant.
L'hypothèse de Stuart est «GRATUITE PEUT PAS SUPPORTER UNE EXCEPTION», et cela peut clairement.
N'oubliez pas, le A code> va également fuir si son destructeur augmente une exception.
En fait, je voulais dire A code> fuira toujours, car la mémoire pour
A code> ne sera définitivement pas libérée, mais vous avez raison de souligner que certaines de ses sous-observations peuvent être.
Merci a tous. Je viens à ce sujet à partir d'un fond de C ++, où les destructeurs pouvant lancer sont un NO sérieux non-non (depuis la lancée tandis que la pile est déroulée à la suite d'une exception précédente std :: terminer code> ), donc j'ai fait la (ce qui s'avère être invalide) en supposant que quelque chose de similaire était le cas à Delphi.
@StuartgolodeZ L'application ne se termine pas sur Delphes Double Exceptions près, mais cela ne signifie pas que l'élévation d'exceptions d'un destructeur est une bonne idée. Vous ne devriez jamais le faire à Delphes non plus. :)
La méthode code> libres > ne constitue pas explicitement une exception, mais elle appelle le destructeur virtuel Donc si vous voulez Assurez-vous que tous vos objets sont détruits, même si l'un des destructeurs augmente une exception, vous vous retrouvez avec un code comme celui-ci: p> ayant dit que, il devrait être une conception Principe que vous ne soulevez pas d'exceptions dans un destructeur. Donc, à mon avis, il est parfaitement raisonnable de prendre le point de vue que si une exception est élevée en destructeur, votre programme est à peu près rechangé. Les objets qui fuient à ce stade ne sont pas quelque chose à craindre. Si votre destructeur a soulevé une exception, vous allez probablement déjà fuir parce que ce destructeur ne s'est pas exécuté à l'achèvement. P> donc à mon avis, il peut être parfaitement raisonnable de regrouper certains appels vers si vous voulez juste un dans ma propre base de code, j'ai quelques méthodes d'assistance qui rendent ce nettoyant . Ensuite, le code peut ressembler à ceci: p> J'ai donné mon détruire code> qui pourrait certainement soulever une exception.
Gratuit Code> et bien sûr, vous éviterez profondément imbriqué
essayer code> /
enfin code> qui est quelque chose qui mérite d'être visible pour. p>
essayer < / code> /
enfin code> puis rappelez-vous d'écrire le code comme celui-ci: p>
freeandnil code> le même nom que la fonction dans
sysutils code> Lequel sur le premier coup d'œil peut sembler étrange, mais c'est sûr et bénin de le faire. Naturellement, ces aides entrent dans leur propre lorsque vous avez encore plus de deux objets. P> P>
Il pourrait y avoir 2 choses pouvant causer Dans votre cas si personnobj.free code> pour soulever une exception: p>
Someobj code> instance de classe ou de ses ancêtres. Li>
TOOOBJ code>. LI>
ol>
a.free code> soulève une exception pour les raisons ci-dessus, il y aurait une fuite de mémoire pour objet
B code> et
C code> et peut-être une fuite à l'intérieur de l'objet
A code> à cause de l'exception non gérée dans lestructeurs. p>
Pourquoi le bowvote hors d'intérêt? C'est une question claire, il n'y a pas d'ambiguïté et je voulais vraiment connaître la réponse. haussement d'épaules i>
Je pense que vous avez accepté une réponse ici trop vite.
@NGLN: D'accord en fait (désolé Tondrej), je pense que la réponse de David est bien meilleure.
@Stuartgolodetz Pas de problème, je suis d'accord.