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?
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?
En C++ 11, vous pouvez utiliser:
class MyClass
{
// create a virtual, default destructor
virtual ~MyClass() = default;
};
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);
}
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...
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).
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.
Non. Vous avez besoin de la déclarer comme virtuel.