Le destructeur par défaut peut-il être généré automatiquement en tant que destructeur virtuel?

Le destructeur par défaut peut-il être généré automatiquement en tant que destructeur virtuel?

Si je définis une classe de base mais pas de destructeur par défaut, y a-t-il un destructeur virtuel par défaut généré automatiquement?

46
demandé sur lc. 2009-07-13 06:03:33

7 réponses

Non. Il y a un coût associé à rendre une méthode virtuelle, et C++ a une philosophie de ne pas vous faire payer pour des choses que vous n'indiquez pas explicitement que vous voulez utiliser. Si un destructeur virtuel avait été généré automatiquement, vous auriez payé le prix automatiquement.

Pourquoi ne pas simplement définir un destructeur virtuel vide?

42
répondu Uri 2009-07-13 02:06:38

En C++ 11, vous pouvez utiliser:

class MyClass
{
  // create a virtual, default destructor
  virtual ~MyClass() = default;
};
46
répondu Drew Noakes 2014-02-01 14:44:19

Uri et Michael ont raison - j'ajouterai simplement que si ce qui vous dérange est de devoir toucher deux fichiers pour déclarer et définir le destructeur, il est parfaitement correct de définir un minimum en ligne dans l'en-tête:

class MyClass
{
   // define basic destructor right here
   virtual ~MyClass(){}

   // but these functions can be defined in a different file
   void FuncA();
   int FuncB(int etc);
}
9
répondu Crashworks 2009-07-13 02:10:40

Non, tous les destructeurs ne sont pas virtuels par défaut.

Vous devrez définir un destructeur virtuel sur toutes les classes de base

En plus de cela.

Pour citer Scott Meyers dans son livre " Effective C++":

La norme de langage c++ est exceptionnellement clair sur ce sujet. Lorsque vous essayez de supprimer une classe dérivée objet via un pointeur de classe de base et la classe de base a un non-virtuel destructeur (comme le fait EnemyTarget), le les résultats sont indéfini

En pratique, c'est généralement une bonne idée de définir une classe avec un destructeur virtuel si vous pensez que quelqu'un pourrait éventuellement en créer une classe dérivée. J'ai tendance à faire en sorte que toutes les classes aient des destructeurs virtuels de toute façon. Oui, il y a un coût associé à cela, mais le coût de ne pas le rendre virtuel plus souvent qui ne pèse pas un peu de frais généraux d'exécution.

Je suggère, seulement le rendre non virtuel quand vous êtes absolument certain que vous le voulez de cette façon plutôt que de compter sur le non-virtuel par défaut que les compilateurs appliquent. Vous pouvez être en désaccord, cependant (en résumé) j'ai récemment eu une horrible fuite de mémoire sur un code hérité où tout ce que j'ai fait était d'ajouter un std::vector dans l'une des classes qui existait depuis plusieurs années. Il s'avère que l'une de ses classes de base n'avait pas de destructeur défini (le destructeur par défaut est vide, non virtuel!) et comme aucune mémoire n'était allouée comme ceci avant qu'aucune mémoire ne fuyait jusqu'à ce point. Beaucoup des jours d'enquête et du temps perdu plus tard...

9
répondu Matt 2009-07-13 03:42:35

Oui, en héritant d'une classe de base avec un destructeur virtuel. Dans ce cas, vous payez déjà le prix d'une classe polymorphe (par exemple vtable).

9
répondu MSalters 2009-07-13 10:27:47

Actuellement, Uri a raison. D'autre part, après avoir déclaré une méthode virtuelle dans votre classe, vous payez le prix de l'existence de la table virtuelle de toute façon. En fait, le compilateur vous avertira si votre classe a une méthode virtuelle, mais pas de destructeur virtuel. Cela pourrait devenir un candidat pour la génération automatique du destructeur virtuel par défaut au lieu de l'avertissement embêtant.

2
répondu Thinkeye 2014-04-07 13:28:30

Non. Vous avez besoin de la déclarer comme virtuel.

1
répondu Michael Aaron Safyan 2009-07-13 02:04:38