58 votes

Compilateur GNU avertissement "de catégorie a des fonctions virtuelles, mais non destructeur virtuel"

J'ai défini une interface en c++, c'est à dire une classe ne contenant que des fonctions virtuelles pures.

Je veux interdire explicitement les utilisateurs de l'interface pour supprimer l'objet par l'intermédiaire d'un pointeur vers l'interface, j'ai donc déclaré protégé et non destructeur virtuel pour l'interface, quelque chose comme:

class ITest{
public:
    virtual void doSomething() = 0;
protected:
    ~ITest(){}
};

void someFunction(ITest * test){
    test->doSomething(); // ok
    // deleting object is not allowed
    // delete test; 
}

Le compilateur GNU me donne un message d'avertissement disant "classe " ITest' a des fonctions virtuelles, mais non destructeur virtuel".

Une fois le destructeur est protégé, quelle est la différence entre l'avoir virtuel ou non virtuel?

Pensez-vous que cet avertissement peut être ignoré ou passé sous silence?

65voto

Greg Rogers Points 18119

C'est plus ou moins un bug du compilateur. Notez que dans les plus récentes versions du compilateur cet avertissement ne pas faire jeter (au moins en 4.3 il n'est pas). Avoir le destructeur être protégés et non virtuel est tout à fait légitime dans votre cas.

Voir ici l'excellent article de Herb Sutter sur le sujet. De l'article:

La ligne directrice n ° 4: Une classe de base destructeur doit être public et virtuel, ou protégés et nonvirtual.

9voto

Airsource Ltd Points 14291

Certains des commentaires sur cette réponse se rapportent à une précédente réponse que j'ai donné, ce qui est faux.

Protégé destructeur, signifie qu'il ne peut être appelé à partir de la classe de base, et non pas par le biais de supprimer. Cela signifie qu'une ITest* ne peut pas être directement supprimés, seule une classe dérivée peut. La classe dérivée peut bien vouloir d'un destructeur virtuel. Il n'y a rien de mal avec votre code.

Cependant, puisque vous ne pouvez pas désactiver localement un avertissement dans GCC, et vous avez déjà une vtable, vous pourriez envisager de simplement faire le destructeur virtuel de toute façon. Il vous en coûtera 4 octets pour le programme (et non par l'instance de classe), maximum. Depuis que vous pourriez avoir donné votre classe dérivée de un virtuel dtor, il se peut que cela ne vous coûte rien.

4voto

bk1e Points 13737

Si vous insistez sur le fait de faire ceci, aller de l'avant et passer -Wno-non-virtual-dtor de GCC. Cet avertissement ne semble pas être activé par défaut, donc vous devez avoir activé il avec -Wall ou -Weffc++. Cependant, je pense que c'est un avertissement utile, parce que, dans la plupart des situations, ce serait un bug.

2voto

MSalters Points 74024

C'est une classe d'interface, il est donc raisonnable, vous ne devez pas supprimer les objets implémentant cette interface via cette interface. Un cas courant de qui est une interface pour les objets créés par une usine qui doit être retourné à l'usine. (Les objets contiennent un pointeur sur leurs réglages d'usine peuvent être assez cher).

Je serai d'accord avec l'observation que GCC est pleurnicher. Au lieu de cela, il faut simplement avertir lorsque vous supprimez un ITest*. C'est là le véritable danger réside.

2voto

Len Holgate Points 12579

Mon avis personnel est que vous auriez du faire la bonne chose et le compilateur est cassé. J'avais désactiver l'avertissement (localement dans le fichier qui définit l'interface) si possible,

Je trouve que l'utilisation de ce modèle (un petit "p") beaucoup. En fait je trouve que c'est plus courant pour mes interfaces pour avoir protégé dtors que c'est pour eux que pour le public, d'avoir. Cependant, je ne pense pas que c'est en fait qu'un idiome commun (il n'est pas parlé tant que ça) et je suppose que le dos lorsque l'avertissement a été ajouté à GCC, il est judicieux d'essayer et d'appliquer les anciennes 'dtor doit être virtuel si vous avez des fonctions virtuelles" la règle. Personnellement, j'ai mis à jour la règle de "dtor doit être virtuel si vous avez des fonctions virtuelles et souhaitez que les utilisateurs soient capables de supprimer les instances de l'interface par le biais de l'interface d'autre de la dtor, doivent être protégés et non virtuelle", il y a des siècles ;)

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