J'ai déjà travaillé dans un paramètre où des exceptions ont été désactivées et l'échec de la mémoire de la mémoire signifie que nous tuerons le programme. Travailler maintenant avec des exceptions, je m'interroge sur la sémantique précise des éléments suivants: ma question est ce qui se passe lorsque nouvelle bar code> lève lorsque
y code> est alloué? Je suppose que le destructeur de
x code> est appelé de sorte que la première allocation est nettoyée. Comment la langue garantit-elle cela? Tout le monde connaît une citation de la norme qui explique la sémantique précise? P> P>
3 Réponses :
Si une exception est lancée lors de la construction d'objets, l'objet était pas em> construit et que vous ne devriez pas faire aucune hypothèse em> sur l'état de tout em> membres. L'objet n'est tout simplement pas utilisable. Tous les membres initialisés avant l'exception étant lancés seront destructés dans l'ordre inverse de leur construction. P>
https://eel.is/c++Draft/basic .Life # def: la vie décrit les règles de vie. P>
Oui, tous les membres complètement construits seront détruits. Votre objet ne sera laissé dans aucune sorte d'état «à moitié vivant». Aucune fuite de mémoire ne se produira.
[sauf.ctor] / 3 code> A>: Si l'initialisation ou la destruction d'un objet autre que par délégation constructeur est terminée par une exception, le destructeur est invoqué pour chacun des sous-coordonnements directs de l'objet et, pour un objet complet, des sous-observations de classe de base virtuelle, dont l'initialisation est terminée ( [DCL.Init]) [..] em> Les sous-observations sont détruites dans l'ordre inverse de l'achèvement de leur construction. [..] em> p> BlockQuote>
Nous pouvons le démontrer nous-mêmes: p>
xxx pré> ( Démo en direct ) h3>
C'est, en fait, l'un des principaux avantages des "pointeurs intelligents": la sécurité des exceptions. Était
x code> un pointeur brut, vous auriez fui la chose qu'il pointe, car une destruction d'un pointeur cru ne fait rien. Avec une sécurité d'exception, vous pouvez avoir RAII; sans elle, bonne chance. P> p>
En outre, l'ordre de construction est l'ordre de la déclaration des membres et strictement séquencé, de sorte que les membres qui auraient appelé leurs destructeurs sont tous ceux déclarés devant celui dont l'initialisateur correspondant se jette.
Si vous êtes inquiet pour les deux premier dans 12 une expression complète est p >
16 Tout calcul de valeur et effet secondaire associé à une
L'expression complète est séquencée avant chaque calcul de la valeur et le côté
effet associé à la prochaine expression complète à évaluer. p>
blockQuote>
sans trop d'aller dans les détails, 13.3 - alors, non Les membres de données statiques sont initialisés dans l'ordre dans lequel elles ont été déclarées dans la définition de la classe (à nouveau indépendamment de la commande.
des initialiseurs de mémoire). P>
blockQuote>
SO Nouvelle barre CODE> Les expressions entrelaciants et jetant avant que les poignées ne soient initialisées pour contenir ce qu'elles sont signifiées, la norme ne le permet pas. P>
x {nouveau bar} code> et
y {nouveau bar} code> dans leur intégralité sont tous deux considérés comme étant considérés comme étant une "expression complète" (Même s'ils ne sont pas des expressions grammaires sage). Les deux paragraphes que j'ai cités indiquent que l'intégralité de l'initialisation de
x code> (qui inclut
nouvelle bar code>) doit se produire d'abord, ou l'intégralité de l'initialisation de
y code > doit arriver en premier. Nous savons de
x code> est initialisé en totalité, puis
y code>. Donc, même si
nouvelle barre code> lors de l'initialisation
y code>,
x code> possède déjà la ressource qu'il est destiné à tenir. Dans ce cas, lorsque l'exception est lancée, le verbiage dans [sauf.ctor] fort> Paringh 3 s'appliquera au
x code> entièrement construit, et il sera détruit, libérant ainsi la ressource. p>
y code> n'est pas "alloué" en soi i>; Son espace mémoire fait partie de celui du
FOO code>. La chose qu'elle pointe est allouée par votre
nouvelle barre code> expression. Faites attention à la terminologie. Je pense que vous vouliez dire "initialisé".