Quelqu'un peut-il aider l'ordre de la destruction lorsque j'utilise des fonctions virtuelles. Commence-t-il avec la classe de base puis de la classe dérivée? P>
8 Réponses :
Les fonctions virtuelles ne font aucune différence pour l'ordre de destruction, des classes de base virtuelles, d'autre part, font. P>
Sans classes de base virtuelles, les classes dérivées sont toujours détruites avant leurs classes de base; C'est l'ordre inverse dans lequel ils sont construits. p>
Pour la classe la plus dérivée, les classes de base virtuelles sont construites en premier, avant d'autres classes de base et avant la classe la plus dérivée elle-même. Destruction arrive dans l'ordre inverse. Cela signifie qu'une base virtuelle peut être détruite après une classe qui en dérive pratiquement, si cette classe n'est pas la classe la plus dérivée étant détruite. Cela ne peut jamais arriver pour les classes de base directes. P>
Évitez donc d'impurer MI dans un environnement sain? Je t'ai eu :)
@Merlyn Morgan-Graham: Qu'entendez-vous par «IMPURE MI»?
Par impure, je veux dire quoi que ce soit où le héritage virtuel importerait. Toute héritage multiple sur les classes de base qui ne sont pas purement abstraites. Je pensais avoir à pré-planter plusieurs héritages avec le mot-clé "virtuel" sur les classes de base était suffisamment désagréable. Trouver l'ordre destructeur / constructeur en rend la situation pire :)
C'est la manière opposée que les constructeurs. Donc dérivé en premier. P>
En supposant que vous avez correctement déclaré votre destructeur comme virtuel. P>
La destruction est terminée dans l'ordre de construction exact de la construction. p>
a) commence dans la classe la plus dérivée.
B) Répétez les suivantes récursives. p>
1) exécuter le code destructeurs.
2) Exécuter le destructeur de chaque membre (dans l'ordre inverse de la création)
3) exécuter le destructeur de la classe mère. (Si plus d'un dans l'ordre inverse de la création) p>
Si vous utilisez un héritage virtuel, les choses sont légèrement différentes car l'ordre de la construction de la classe de base n'est pas la même chose que la normale. mais b> L'ordre de destruction est Toujours B> l'inverse de l'ordre de construction. P>
ordre des destructions si de bas en haut. (de dérivé à la base) p>
Réponse courte: l'exact opposé de l'ordre du constructeur. p>
long réponse: supposons que le "le plus "classe dérivée est d, ce qui signifie la objet réel qui était à l'origine créé était de la classe D et que d hérite de multiplier (et de non-pratiquement) de b1 et b2. Le sous-objet Correspondant à la classe D la plupart dérivée D fonctionne en premier, suivi des dtors pour ses classes de base non virtuelles dans Déclaration inverse-commande. Ainsi, le L'ordre destructeur sera D, B2, B1. Cette règle est appliquée de manière récursive; pour exemple, si B1 hérite de B1A et B1B, et B2 hérite de B2A et B2B, La commande finale est D, B2, B2B, B2A, B1, B1B, B1A. P> blockQuote>
Voir le C ++ FAQ Section 25 A > p>
L'ordre de destruction est l'ordre de construction en arrière. J'ai récemment fait un petit outil pour afficher l'ordre de construction pour toute hiérarchie. Regardez ici: p>
Dans les diagrammes, les nœuds avec les plus petits nombres sont construits
premier le dérivé, puis la base. Aucune différence WRT les cas non virtuels.
Note supplémentaire. Lorsque vous avez des méthodes héritables et virtuelles, vous devez déclarer destructeurs comme virtuels, sinon vous pouvez avoir un comportement indéfini à la suppression. P>
exemple, supposé dérivé est dérivé de base et vous allouez dérivé avec la ligne suivante: P>
Base *o = new Derived(); delete(o);
Pas strictement précis. Si base code> n'a pas de destructeur virtuel, le comportement n'est pas défini. Il peut ne pas être le cas que
base code> ou
dérivé code> les destructeurs sont appelés ou que le programme pourrait simplement planter.
Puisque je ne vois pas comment la fonction virtuelle change d'ordre de destruction des objets, je suppose que vous parlez de l'ordre de destruction pour les classes de base et les membres de données dans un héritage virtuel em> strong> scénario. p>
Les sous-objets sont destruction em> strong> est simplement le contraire de construction em>, vous n'avez donc besoin que de mémoriser ce qui précède. p>
Cependant, les quatre règles ci-dessus sont dans cet ordre, car cela a du sens, et si vous comprenez pourquoi cette commande a du sens, vous n'aurez même pas à mémoriser ces quatre règles, mais que je peux en déduire de votre compréhension (comme je viens de fait). Alors examinons cet ordre: p>
En fait, je pense qu'il a parlé d'un destructeur virtuel code>.
@Matthieu: Cela semble que j'avais raison. :) code> (merci de la fixation de la grammaire!)
Section 12.6.2 / 5: P>
L'initialisation doit procéder à l'ordre suivant: P>
- premier, et seulement pour le constructeur de la classe la plus dérivée comme décrit ci-dessous, les classes de base virtuelles doivent être initialisées dans la commandez, ils apparaissent sur une traversée de la profondeur-gauche à droite de la graphique acyclique dirigé des classes de base, où "gauche à droite" est le ordre d'apparition des noms de classe de base dans la classe dérivée Liste de la spécification de base. Li>
- Ensuite, les classes de base directe doivent être initialisées Dans l'ordre de déclaration comme ils apparaissent dans la liste de spécifications de base (quel que soit l'ordre des initialiseurs de Mem). LI>
- alors, non artistique Les membres de données doivent être initialisés dans l'ordre dans lequel ils ont été déclarés dans la définition de la classe (à nouveau indépendamment de l'ordre du initialiseurs de Mem). - Enfin, le corps du constructeur est exécuté. Li> ul>
[Note: L'ordre de déclaration est chargé de s'assurer que la base et Les sous-observations membres sont détruites dans l'ordre inverse de initialisation. ] p> blockQuote>