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?
Non. La virtualisation d'une méthode a un coût et C++ a pour philosophie de ne pas vous faire payer pour des choses que vous ne déclarez pas explicitement que vous souhaitez utiliser. Si un destructeur virtuel avait été généré automatiquement, vous en auriez payé le prix automatiquement.
Pourquoi ne pas simplement définir un destructeur virtuel vide?
En C++ 11, vous pouvez utiliser:
class MyClass
{
// create a virtual, default destructor
virtual ~MyClass() = default;
};
Non, tous les destructeurs ne sont PAS par défaut virtuels.
Vous devrez définir un destructeur virtuel sur toutes les classes de base
En plus de ça.
Pour citer Scott Meyers dans son livre "Effective C++":
Le standard du langage C++ est exceptionnellement clair sur ce sujet. Lorsque vous essayez de supprimer un objet de classe dérivée via un pointeur de classe de base et que la classe de base a un destructeur non virtuel (comme le fait EnemyTarget), les résultats ne sont pas définis
Dans la 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 un destructeur virtuel 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 lourd fardeau de temps d'exécution.
Je suggère de le rendre non virtuel uniquement lorsque vous êtes absolument certain de le vouloir de cette façon plutôt que de vous fier au 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 fuite de mémoire horrible sur un code hérité où tout ce que j'ai fait a été d'ajouter un std :: vector dans l'une des classes qui existaient 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 ça avant qu'aucune mémoire ne fuit jusqu'à ce point. De nombreux jours d'enquête et du temps perdu plus tard ...
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).
Uri et Michael ont raison - j'ajouterai simplement que si ce qui vous dérange est de toucher deux fichiers pour déclarer et définir le destructeur, il est parfaitement normal d'en 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);
}
Actuellement, ri a raison. D'un autre côté, après avoir déclaré une méthode virtuelle dans votre classe, vous payez quand même le prix de l'existence de la table virtuelle. 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.
Non. Vous devez le déclarer virtuel.