10
votes

ordre de destruction en utilisant virtuel

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?


0 commentaires

8 Réponses :


0
votes

Les fonctions virtuelles ne font aucune différence pour l'ordre de destruction, des classes de base virtuelles, d'autre part, font.

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.

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.


3 commentaires

É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 :)



0
votes

C'est la manière opposée que les constructeurs. Donc dérivé en premier.


0 commentaires

5
votes

En supposant que vous avez correctement déclaré votre destructeur comme virtuel.

La destruction est terminée dans l'ordre de construction exact de la construction.

En général, ce sera:

a) commence dans la classe la plus dérivée.
B) Répétez les suivantes récursives.

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)

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 L'ordre de destruction est Toujours l'inverse de l'ordre de construction.


0 commentaires

0
votes

ordre des destructions si de bas en haut. (de dérivé à la base)

Réponse courte: l'exact opposé de l'ordre du constructeur.

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.

Voir le C ++ FAQ Section 25


0 commentaires


0
votes

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);


1 commentaires

Pas strictement précis. Si base n'a pas de destructeur virtuel, le comportement n'est pas défini. Il peut ne pas être le cas que base ou dérivé les destructeurs sont appelés ou que le programme pourrait simplement planter.



14
votes

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 scénario.

Les sous-objets sont construits

  1. classes de base sont construits de la plupart des bases à la plus dérivées ;
  2. Les classes de base multiples sont construites dans l'ordre de leur déclaration comme classes de base ;
  3. classes de base virtuelles sont construits avant tous les autres , entre eux adhérant aux deux règles ci-dessus;
  4. Membres de données sont construits avant que le corps du constructeur de l'objet enfermé soit exécuté , dans l'ordre de leur déclaration.

    destruction est simplement le contraire de construction , vous n'avez donc besoin que de mémoriser ce qui précède.

    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:

    • Vous voudrez peut-être utiliser le service que la classe de base fournit d'un constructeur de classe dérivé. Bien sûr, vous ne pouvez pas utiliser un objet de classe (base) avant qu'il ne soit réellement construit. Par conséquent, lorsqu'une classe dérivée est construite, la classe de base doit être déjà construite. (Incidemment, cela explique également pourquoi la répartition de la fonction virtuelle ne fonctionne pas complètement à partir de constructeurs: lorsqu'un sous-objet est construit, seuls les sous-objets des classes de base sont déjà construits; les sous-objets de classes dérivés ne sont pas encore construit. Par conséquent, un appel à une fonction virtuelle ne doit pas être expédié à une classe dérivée. Comme toujours, les destructeurs sont identiques, juste en arrière.)
    • Avec plusieurs classes de base étant égales en frères et sœurs, une ordonnance devait être cueillie de manière arbitraire. En fin de compte, l'ordre de déclaration est le plus simple à utiliser. Les membres de données, qui sont également des frères et sœurs égaux, suivent la même règle (plus ou moins arbitraire) dans l'ordre de la déclaration de déclaration.
    • Les classes de base virtuelles sont des bêtes étranges. Parce qu'il n'y aura toujours qu'un sous-objet d'une classe de base virtuelle, il y a cette règle spéciale qui dit qu'il doit toujours être construite en premier, à partir du constructeur de classe le plus dérivé. (C'est pourquoi les classes de base virtuelles fonctionnent mieux comme des classes de base abstraites sans données et uniquement des constructeurs par défaut.)

2 commentaires

En fait, je pense qu'il a parlé d'un destructeur virtuel .


@Matthieu: Cela semble que j'avais raison. :) (merci de la fixation de la grammaire!)



1
votes

Section 12.6.2 / 5:

L'initialisation doit procéder à l'ordre suivant:

  • 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.
  • 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).
  • 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é.

    [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. ]


0 commentaires