247 votes

Mot-clé "virtual" en C++ pour les fonctions dans les classes dérivées. Est-il nécessaire ?

Avec la définition structurée donnée ci-dessous...

struct A {
    virtual void hello() = 0;
};

Approche n° 1 :

struct B : public A {
    virtual void hello() { ... }
};

Approche n°2 :

struct B : public A {
    void hello() { ... }
};

Y a-t-il une différence entre ces deux façons de remplacer la fonction hello ?

70 votes

En C++11, vous pouvez écrire "void hello() override {}" pour déclarer explicitement que vous surchargez une méthode virtuelle. Le compilateur échouera si une méthode virtuelle de base n'existe pas, et cela a la même lisibilité que de placer "virtual" sur la classe descendante.

0 votes

En fait, dans le C++11 de gcc, écrire void hello() override {} dans la classe dérivée ne pose pas de problème car la classe de base a spécifié que la méthode hello() est virtuelle. En d'autres termes, l'utilisation du mot virtual dans l'expression dérivé de n'est pas nécessaire/obligatoire, pour gcc/g++ en tout cas. (J'utilise gcc version 4.9.2 sur une RPi 3) Mais c'est une bonne pratique d'inclure le mot-clé virtual dans la méthode de la classe dérivée de toute façon.

212voto

James McNellis Points 193607

Ils sont exactement les mêmes. Il n'y a aucune différence entre elles, si ce n'est que la première approche nécessite plus de saisie et est potentiellement plus claire.

27 votes

C'est vrai, mais le guide de portabilité de Mozilla C++ recommande de toujours utiliser virtual parce que "certains compilateurs" émettent des avertissements si vous ne le faites pas. Dommage qu'ils ne mentionnent aucun exemple de ces compilateurs.

6 votes

J'ajouterais également que le fait de marquer explicitement le destructeur comme virtuel vous rappellera qu'il doit lui aussi être virtuel.

1 votes

Je tiens à préciser qu'il en va de même pour destructeur virtuel

93voto

Clifford Points 29933

La "virtualité" d'une fonction est propagée implicitement, cependant au moins un compilateur que j'utilise génère un avertissement si la fonction virtual n'est pas utilisé explicitement, donc vous pouvez vouloir l'utiliser, ne serait-ce que pour que le compilateur reste silencieux.

D'un point de vue purement stylistique, inclure la virtual Le mot clé "annonce" clairement à l'utilisateur que la fonction est virtuelle. Ce sera important pour toute personne qui sous-classe ultérieurement B sans avoir à vérifier la définition de A. Pour les hiérarchies de classes profondes, cela devient particulièrement important.

35 votes

@James : armcc (le compilateur d'ARM pour les dispositifs ARM)

65voto

R Sahu Points 24027

El virtual n'est pas nécessaire dans la classe dérivée. Voici la documentation à l'appui, tirée du projet de norme C++ (N3337) (c'est moi qui souligne) :

10.3 Fonctions virtuelles

2 Si une fonction membre virtuelle vf est déclaré dans une classe Base et dans une classe Derived dérivés directement ou indirectement de Base une fonction membre vf avec le même nom, la même liste de types de paramètres (8.3.5), la même qualification cv et le même qualificateur ref (ou l'absence de celui-ci) que Base::vf est déclaré, alors Derived::vf est également virtuel ( qu'elle soit ou non déclarée telle ) et il remplace Base::vf .

6 votes

C'est de loin la meilleure réponse ici.

13voto

Sujay Ghosh Points 1563

L'ajout du mot clé "virtual" est une bonne pratique car il améliore la lisibilité, mais il n'est pas nécessaire. Les fonctions déclarées virtuelles dans la classe de base, et ayant la même signature dans les classes dérivées sont considérées comme "virtuelles" par défaut.

8voto

harper Points 5962

Il n'y a pas de différence pour le compilateur, lorsque vous écrivez la balise virtual dans la classe dérivée ou l'omettre.

Mais vous devez regarder la classe de base pour obtenir cette information. C'est pourquoi je recommande d'ajouter l'élément virtual également dans la classe dérivée, si vous voulez montrer à l'humain que cette fonction est virtuelle.

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