Qu'est-ce que cela signifie exactement si une fonction est définie comme virtuelle et est-ce la même chose que virtuelle pure?
De la fonction virtuelle de Wikipedia ...
Dans la programmation orientée objet, dans des langages tels que C ++ et Object Pascal, une fonction virtuelle ou une méthode virtuelle est une fonction ou une méthode héritable et remplaçable pour laquelle la répartition dynamique est facilitée. Ce concept est une partie importante de la portion (d'exécution) du polymorphisme de la programmation orientée objet (POO). En bref, une fonction virtuelle définit une fonction cible à exécuter, mais la cible peut ne pas être connue au moment de la compilation.
Contrairement à une fonction non virtuelle, lorsqu'une fonction virtuelle est remplacée, la version la plus dérivée est utilisée à tous les niveaux de la hiérarchie des classes, plutôt qu'au niveau auquel elle a été créée. Par conséquent, si une méthode de la classe de base appelle une méthode virtuelle, la version définie dans la classe dérivée sera utilisée à la place de la version définie dans la classe de base.
Cela contraste avec les fonctions non virtuelles, qui peuvent toujours être remplacées dans une classe dérivée, mais la "nouvelle" version ne sera utilisée que par la classe dérivée et ci-dessous, mais ne changera pas du tout la fonctionnalité de la classe de base.
tandis que..
Une fonction virtuelle pure ou une méthode virtuelle pure est une fonction virtuelle qui doit être implémentée par une classe dérivée si la classe dérivée n'est pas abstraite.
Lorsqu'une méthode virtuelle pure existe, la classe est "abstraite" et ne peut pas être instanciée seule. Au lieu de cela, une classe dérivée qui implémente la ou les méthodes pure-virtuelles doit être utilisée. Un virtuel pur n'est pas du tout défini dans la classe de base, donc une classe dérivée doit le définir, ou cette classe dérivée est également abstraite et ne peut pas être instanciée. Seule une classe qui n'a pas de méthodes abstraites peut être instanciée.
Un virtuel fournit un moyen de remplacer la fonctionnalité de la classe de base, et un pur-virtuel l' exige .
pure
mot - clé, mais que Bell Labs était sur le point de faire une version majeure de C ++, et son manager ne l'autoriserait pas à ce stade tardif. L'ajout de mots clés est un gros problème.Je voudrais commenter la définition de Wikipédia du virtuel, comme plusieurs l'ont répété ici. [Au moment où cette réponse a été écrite,] Wikipedia a défini une méthode virtuelle comme une méthode qui peut être remplacée dans les sous-classes. [Heureusement, Wikipédia a été modifié depuis, et il explique maintenant cela correctement.] C'est incorrect: toute méthode, pas seulement virtuelle, peut être remplacée dans les sous-classes. Ce que le virtuel fait est de vous donner un polymorphisme, c'est-à-dire la possibilité de sélectionner au moment de l'exécution le remplacement le plus dérivé d'une méthode .
Considérez le code suivant:
Quelle est la sortie de ce programme?
Derived remplace toutes les méthodes de Base: non seulement la virtuelle, mais aussi la non-virtuelle.
Nous voyons que lorsque vous avez un pointeur de base vers dérivé (bDerived), appeler NonVirtual appelle l'implémentation de la classe de base. Ceci est résolu au moment de la compilation: le compilateur voit que bDerived est une Base *, que NonVirtual n'est pas virtuel, donc il fait la résolution sur la classe Base.
Cependant, l'appel de Virtual appelle l'implémentation de la classe Derived. En raison du mot-clé virtual, la sélection de la méthode se produit au moment de l' exécution , pas au moment de la compilation. Ce qui se passe ici au moment de la compilation, c'est que le compilateur voit qu'il s'agit d'une Base *, et qu'il appelle une méthode virtuelle, donc il insère un appel à la table virtuelle au lieu de la classe Base. Cette table virtuelle est instanciée au moment de l'exécution, d'où la résolution au moment de la substitution la plus dérivée.
J'espère que ce n'était pas trop déroutant. En bref, n'importe quelle méthode peut être remplacée, mais seules les méthodes virtuelles vous donnent le polymorphisme, c'est-à-dire la sélection au moment de l'exécution du remplacement le plus dérivé. Dans la pratique, cependant, remplacer une méthode non virtuelle est considéré comme une mauvaise pratique et rarement utilisé, de nombreuses personnes (y compris celui qui a écrit cet article Wikipedia) pensent que seules les méthodes virtuelles peuvent être remplacées.
la source
Derived*
avec les mêmes appels de fonction pour ramener le point d'origine. Sinon, bonne réponseLe mot-clé virtuel donne à C ++ sa capacité à supporter le polymorphisme. Lorsque vous avez un pointeur sur un objet d'une classe telle que:
Dans cet exemple (idiot), la fonction GetNumberOfLegs () renvoie le nombre approprié en fonction de la classe de l'objet pour lequel il est appelé.
Maintenant, considérez la fonction 'SomeFunction'. Peu importe le type d'objet animal qui lui est transmis, tant qu'il est dérivé d'Animal. Le compilateur convertira automatiquement toute classe dérivée d'un animal en animal car il s'agit d'une classe de base.
Si nous faisons cela:
il produirait «2». Si nous faisons cela:
il produirait «4». On ne peut pas faire ça:
car il ne se compile pas car la fonction virtuelle GetNumberOfLegs () est pure, ce qui signifie qu'elle doit être implémentée en dérivant des classes (sous-classes).
Les fonctions virtuelles pures sont principalement utilisées pour définir:
a) classes abstraites
Ce sont des classes de base où vous devez en dériver puis implémenter les fonctions virtuelles pures.
b) interfaces
Ce sont des classes «vides» où toutes les fonctions sont entièrement virtuelles et donc vous devez dériver puis implémenter toutes les fonctions.
la source
Dans une classe C ++, virtual est le mot-clé qui désigne cela, une méthode peut être remplacée (c'est-à-dire implémentée par) une sous-classe. Par exemple:
Dans ce cas, une sous-classe peut remplacer la fonction initShape pour effectuer un travail spécialisé:
Le terme virtuel pur fait référence aux fonctions virtuelles qui doivent être implémentées par une sous-classe et qui n'ont pas été implémentées par la classe de base. Vous désignez une méthode comme virtuelle pure en utilisant le mot clé virtual et en ajoutant a = 0 à la fin de la déclaration de méthode.
Donc, si vous vouliez rendre Shape :: initShape pur virtuel, vous feriez ce qui suit:
En ajoutant une méthode virtuelle pure à votre classe, vous faites de la classe une classe de base abstraite qui est très pratique pour séparer les interfaces de l'implémentation.
la source
m_name
. Qu'est-ce que celam_
signifie?"Virtuel" signifie que la méthode peut être remplacée dans les sous-classes, mais a une implémentation directement appelable dans la classe de base. "Virtuel pur" signifie qu'il s'agit d'une méthode virtuelle sans implémentation directement appelable. Une telle méthode doit être remplacée au moins une fois dans la hiérarchie d'héritage - si une classe a des méthodes virtuelles non implémentées, les objets de cette classe ne peuvent pas être construits et la compilation échouera.
@quark souligne que les méthodes pure-virtual peuvent avoir une implémentation, mais comme les méthodes pure-virtual doivent être remplacées, l'implémentation par défaut ne peut pas être appelée directement. Voici un exemple d'une méthode pure-virtuelle avec une valeur par défaut:
Selon les commentaires, l'échec de la compilation est spécifique au compilateur. Dans GCC 4.3.3 au moins, il ne compilera pas:
Production:
la source
Comment fonctionne le mot-clé virtuel?
Supposons que l'homme est une classe de base, l'indien est dérivé de l'homme.
Déclarer do_work () comme virtuel signifie simplement: quel do_work () appeler sera déterminé UNIQUEMENT au moment de l'exécution.
Supposons que je le fasse,
Si virtual n'est pas utilisé, le même est statiquement déterminé ou lié statiquement par le compilateur, selon l'objet qui appelle. Donc, si un objet de Man appelle do_work (), le do_work () de Man est appelé MÊME QUAND IL POINT SUR UN OBJET INDIEN
Je crois que la réponse la plus votée est trompeuse - Toute méthode, virtuelle ou non, peut avoir une implémentation remplacée dans la classe dérivée. En ce qui concerne spécifiquement C ++, la différence correcte est la liaison au moment de l'exécution (lorsque le virtuel est utilisé) et la compilation (lorsque le virtuel n'est pas utilisé mais qu'une méthode est remplacée et qu'un pointeur de base pointe vers un objet dérivé) la liaison des fonctions associées.
Il semble y avoir un autre commentaire trompeur qui dit:
C'EST FAUX! Les fonctions purement virtuelles peuvent également avoir un corps ET PEUVENT ÊTRE MISES EN ŒUVRE! La vérité est que la fonction virtuelle pure d'une classe abstraite peut être appelée statiquement! Deux très bons auteurs sont Bjarne Stroustrup et Stan Lippman .... parce qu'ils ont écrit la langue.
la source
Une fonction virtuelle est une fonction membre déclarée dans une classe de base et redéfinie par une classe dérivée. Les fonctions virtuelles sont hiérarchiques par ordre d'héritage. Lorsqu'une classe dérivée ne remplace pas une fonction virtuelle, la fonction définie dans sa classe de base est utilisée.
Une fonction virtuelle pure est une fonction qui ne contient aucune définition par rapport à la classe de base. Il n'a aucune implémentation dans la classe de base. Toute classe dérivée doit remplacer cette fonction.
la source
Simula, C ++ et C #, qui utilisent la liaison de méthode statique par défaut, le programmeur peut spécifier que des méthodes particulières doivent utiliser la liaison dynamique en les étiquetant comme virtuelles. La liaison de méthode dynamique est au cœur de la programmation orientée objet.
La programmation orientée objet nécessite trois concepts fondamentaux: l'encapsulation, l'héritage et la liaison de méthode dynamique.
la source
Les méthodes virtuelles PEUVENT être écrasées en dérivant des classes, mais ont besoin d'une implémentation dans la classe de base (celle qui sera écrasée)
Les méthodes virtuelles pures n'ont pas d'implémentation de la classe de base. Ils doivent être définis par des classes dérivées. (Donc, techniquement, ce n'est pas le bon terme, car il n'y a rien à remplacer).
Virtual correspond au comportement java par défaut, lorsque la classe dérivée remplace une méthode de la classe de base.
Les méthodes Pure Virtual correspondent au comportement des méthodes abstraites au sein des classes abstraites. Et une classe qui ne contient que des méthodes et des constantes virtuelles pures serait le cpp-pendant d'une interface.
la source
Fonction virtuelle pure
essayez ce code
Dans la classe anotherClass, supprimez la fonction sayHellow et exécutez le code. vous obtiendrez une erreur! Parce que lorsqu'une classe contient une fonction virtuelle pure, aucun objet ne peut être créé à partir de cette classe et il est hérité alors sa classe dérivée doit implémenter cette fonction.
Fonction virtuelle
essayez un autre code
Ici, la fonction sayHellow est marquée comme virtuelle dans la classe de base.Elle dit le compilateur qui essaie de rechercher la fonction dans la classe dérivée et implémente la fonction.Si elle n'est pas trouvée, exécutez la base.Merci
la source
"Une fonction virtuelle ou une méthode virtuelle est une fonction ou une méthode dont le comportement peut être remplacé dans une classe héritée par une fonction avec la même signature" - wikipedia
Ce n'est pas une bonne explication pour les fonctions virtuelles. Parce que, même si un membre n'est pas virtuel, l'héritage des classes peut le remplacer. Vous pouvez essayer de le voir vous-même.
La différence se montre lorsqu'une fonction prend une classe de base comme paramètre. Lorsque vous donnez une classe héritée en entrée, cette fonction utilise l'implémentation de classe de base de la fonction surchargée. Cependant, si cette fonction est virtuelle, elle utilise celle qui est implémentée dans la classe dérivée.
la source
Les fonctions virtuelles doivent avoir une définition dans la classe de base et également dans la classe dérivée, mais pas nécessaire, par exemple la fonction ToString () ou toString () est une fonction virtuelle afin que vous puissiez fournir votre propre implémentation en la remplaçant dans la ou les classes définies par l'utilisateur.
Les fonctions virtuelles sont déclarées et définies en classe normale.
La fonction virtuelle pure doit être déclarée se terminant par "= 0" et elle ne peut être déclarée qu'en classe abstraite.
Une classe abstraite ayant une ou des fonctions virtuelles pures ne peut pas avoir de définition (s) de ces fonctions virtuelles pures, ce qui implique que l'implémentation doit être fournie dans des classes dérivées de cette classe abstraite.
la source