108 votes

Quand ne devriez-vous pas utiliser de destructeurs virtuels?

Existe-t-il une bonne raison de ne pas déclarer un destructeur virtuel pour une classe? Quand faut-il éviter spécifiquement d'en écrire un?

82voto

sep Points 1757

Il n'est pas nécessaire d'utiliser un destructeur virtuel lorsque l'une des conditions ci-dessous est vraie:

  • Aucune intention d'en tirer des cours
  • Pas d'instanciation sur le tas
  • Aucune intention de stocker dans un pointeur d'une super-classe

Aucune raison spécifique pour l'éviter à moins d'être vraiment pressé par la mémoire.

75voto

Richard Corden Points 12292

Pour répondre à la question explicitement, c'est à dire. quand devriez-vous pas déclarer un destructeur virtuel.

L'ajout d'un destructeur virtuel peut changer votre classe de POD (Plain Old Données)* ou Agrégées Non-POD. Cela peut empêcher votre projet à partir de la compilation si votre classe est de type agrégat initialisé quelque part.

Dans un cas extrême, une telle modification peut également provoquer un comportement indéterminé où la classe est utilisé n une manière qui nécessite un module, par exemple. en passant par des points de suspension paramètre, ou de l'utiliser avec memcpy.

* D'un type POD est un type qui a des garanties spécifiques au sujet de sa disposition de la mémoire. La norme vraiment indique seulement que si vous copiez à partir d'un objet avec un type POD dans un tableau de caractères (ou non signé caractères) et de retour à nouveau, alors le résultat sera le même que l'objet d'origine.]

30voto

Andy Points 519

Je déclare un destructeur virtuel si et seulement si j'ai des méthodes virtuelles. Une fois que j'ai des méthodes virtuelles, je ne me fais pas confiance pour éviter de l'instancier sur le tas ou de stocker un pointeur sur la classe de base. Ces deux opérations sont extrêmement courantes et entraînent souvent des fuites silencieuses de ressources si le destructeur n’est pas déclaré virtuel.

7voto

Jay Conrod Points 12375

Un destructeur virtuel est nécessaire à chaque fois que il y a toute chance qu' delete pourrait être appelé un pointeur vers un objet d'une sous-classe du type de votre classe. Cela vous permet de vérifier le bon destructeur est appelé au moment de l'exécution, sans que le compilateur avoir à connaître la classe d'un objet sur le tas au moment de la compilation. Par exemple, supposons B est une sous-classe de A:

A *x = new B;
delete x;     // ~B() called, even though x has type A*

Si votre code n'est pas critique pour les performances, il serait raisonnable d'ajouter un destructeur virtuel pour chaque classe de base, vous écrire, juste pour la sécurité.

Toutefois, si vous avez trouvé vous-même deleteing beaucoup d'objets dans une boucle serrée, la charge de l'appel d'une fonction virtuelle (même vide) peut être sensiblement. Le compilateur ne peut pas habituellement inline ces appels, et le processeur peut avoir un moment difficile de prédire où aller. Il est peu probable que cela aurait un impact significatif sur les performances, mais il vaut la peine de mentionner.

5voto

mxcl Points 5921

Les fonctions virtuelles signifient que chaque objet alloué augmente les coûts de la mémoire grâce à un pointeur de table de fonctions virtuelles.

Donc, si votre programme implique l’allocation d’un très grand nombre d’objets, il serait utile d’éviter toutes les fonctions virtuelles afin d’économiser les 32 bits supplémentaires par objet.

Dans tous les autres cas, vous éviterez les problèmes de débogage pour rendre le serveur virtuel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X