Différence entre un appel de fonction virtuel et non virtuel de la fonction?
C'est en fait une question d'entrevue, je ne peux pas trouver la réponse. Quelqu'un sait ce que c'est?
Vous pouvez parler de tout la différence, par exemple, les données qui sont push dans la pile.
Quel est exactement votre question?
Une fonction virtuelle subit la distribution dynamique. Vous devez choisir une bonne C++ livre pour apprendre mieux.
Je pense que la question est un peu vague. Quel genre de différence que cela signifie? Différence sur la sémantique du code niveau, compilateur niveau ou à la machine?
Une fonction virtuelle subit la distribution dynamique. Vous devez choisir une bonne C++ livre pour apprendre mieux.
Je pense que la question est un peu vague. Quel genre de différence que cela signifie? Différence sur la sémantique du code niveau, compilateur niveau ou à la machine?
OriginalL'auteur cheng | 2012-01-08
Vous devez vous connecter pour publier un commentaire.
Si virtualism/répartition dynamique est strictement définie par l'implémentation, la plupart(lire tous connu) compilateurs mettre en œuvre, en utilisant
vptr
etvtable
.Cela dit, la différence entre l'appel d'une non virtuel de la fonction et de la fonction virtuelle est:
Non-fonctions virtuelles sont résolus
statically
àCompile-time
, Tandis que les fonctions Virtuelles sont résolusdynamically
àRun-time
.Pour atteindre cette flexibilité de pouvoir décider quelle fonction appeler au moment de l'exécution,
il y a un peu de surcharge dans le cas de fonctions virtuelles.
Supplémentaires
fetch
appel qui doit être fait et c'est la surcharge/prix que vous payez pour l'utilisation de la dynamique de l'expédition.En cas de non-virtuel de la fonction de la séquence d'appels est:
Le compilateur a besoin de
fetch
l'adresse de la fonction, puiscall
.Alors que dans le cas de fonctions virtuelles, la séquence est:
Le compilateur a besoin de
fetch
lavptr
de lathis
, puisfetch
l'adresse de la fonction à partir de lavptr
et puiscall
la fonction.C'est juste une explication simplifiée de la séquence réelle peut-être beaucoup plus complexe que cela, mais c'est ce que vous avez vraiment besoin de savoir, On n'a pas vraiment besoin de savoir la mise en œuvre nitty gritty.
Bonne Lecture:
Héritage & Fonctions Virtuelles
Ajout d'un lien, qui donne une bonne explication de tous les détails.
Il aide vraiment. Merci.
Il pourrait être intéressant de considérer l'effet sur la mise en cache et de pipeline et de la localité de mémoire que le niveau supplémentaire d'indirection. Ce qui semble simple sur le papier peut avoir des effets négligeables dans la pratique.
La séquence pour une fonction non virtuelle est
call
. La séquence pour un pointeur de fonction estfetch-call
. Une vtable ajoute un autrefetch
.OriginalL'auteur Alok Save
Si vous avez une base de classe de Base et la classe dérivée de "Dérivés" et vous avez une fonction " func () définie comme virtuelle dans la classe de Base. Cette func est remplacée par la classe Dérivée.
Supposons que vous définissez
Puis le "func" de la classe Dérivée est appelée. Tandis que si "func () n'a pas été défini comme virtuel à la Base, alors il serait appelé à partir de la "Base" de la classe. C'est la différence de la fonction d'appel diffère pour virtuel et non virtuel fonctions
obj
doit être un pointeur. 2. Apt de mentionner que la overidding fonctionDerived::func()
devraient prendre les mêmes arguments à overidding laBase::func()
Il n'est pas un point subtil, mais d'une importance cruciale. "obj.func()" n'ira pas en appel de la méthode de classe de base, mais on a à utiliser des pointeurs et de l'appeler "obj->func()" de faire usage de méthodes virtuelles.
Notez que l'on peut utiliser des références plutôt que des pointeurs, mais pas toujours dans les mêmes situations. Par exemple, une référence ne peut pas être reprise pour faire référence à un autre objet.
OriginalL'auteur Shraddha
Lors de l'appel d'une méthode virtuelle, il doit rechercher quelle fonction appeler une fonction virtuelle table.
Je ne sais pas comment beaucoup plus accès virtuel appels de méthode ont que les non-virtuel appels de méthode ont (je suppose que l'une ou les deux), mais virtuels les appels de méthode avez besoin d'un peu plus de travail.
OK, je vais essayer de comprendre cela. Je vous remercie.
La accepté de répondre à offrir une bonne lecture sur ce problème. Voir ci-dessus.
OriginalL'auteur icktoofay
La surcharge de l'appel d'une méthode virtuelle est importante.
Aussi cette.
OriginalL'auteur Robert Allan Hennigan Leahy
Non-membre virtuel fonctions sont résolus de manière statique. fonction de membre sont liaison statiquement à la compilation en fonction du type du pointeur de la souris (ou de référence) à l'objet.
En revanche, virtuel fonctions de membre sont de liaison de manière dynamique au moment de l'exécution. Si les élèves ont au moins une fonction membre virtuelle puis compilateur met un pointeur caché dans l'objet appelé un vptr(table virtuelle adresse) lors de la construction de l'objet.
La compilateur crée un v-table pour chaque classe qui a au moins une fonction virtuelle. Table virtuelle contenir virtuel adresse de la fonction. Il peut être de tableau ou de la liste(dépend du compilateur) de la fonction virtuelle du pointeur
Lors d'un envoi d'une fonction virtuelle, le système d'exécution suivante de l'objet v-pointeur(chercher l'adresse de la classe de l'objet) de la classe v-table, puis décalage est ajouté à l'adresse de base(vptr) et d'appeler la fonction.
La espace-coût surcharge de la technique ci-dessus est nominale: un pointeur supplémentaire par objet (mais seulement pour les objets qu'il sera nécessaire de faire de liaison dynamique), plus un supplément de pointeur par méthode (mais seulement pour les méthodes virtuelles).
Le temps-coût surcharge est également assez minime: par rapport à la normale de la fonction d'appel, un appel de fonction virtuelle nécessite deux extra-extrait (un pour obtenir la valeur de la v-pointeur, une seconde pour obtenir l'adresse de la méthode).
Rien de tout cela exécution de l'activité se produit avec les fonctions virtuelles, puisque le compilateur résout non-fonctions virtuelles exclusivement au moment de la compilation en fonction du type du pointeur.
J'ai pris l'exemple simple pour comprendre au mieux, la manière dont la liaison qui s'est passé pour les non virtuel de la fonction & fonction virtuelle et comment fonction virtuelle mécanisme fonctionne.
Comment la vtable créé pour la Base & classe dérivée
Code assembleur généré pour une meilleure compréhension.
J'ai récupéré les informations de la vtable de virtuel.s de Base et la classe Dérivée respectivement:
Comme vous pouvez le voir fun & fun1 ne sont que deux des fonctions virtuelles dans la classe de Base. Vtable de la classe de Base(_ZTV4Base) ont des entrées à la fois des fonctions virtuelles. Vtable n'a pas d'entrée de fonction non virtuelle. S'il vous plaît ne pas confondre avec le nom de l'amusement(ZN4Base3funEv) & fun1(ZN4Base4fun1Ev), leurs noms ont été déformés.
Classe dérivée vtable des arbres entrées
Comment non virtuel de la fonction & fonction virtuelle appelée?
pour les non-fonction virtuelle
Dire simplement, chercher et appeler get(liaison qui s'est passé au moment de la compilation)
pour les non-fonction virtuelle
récupérer le vptr, ajoutez la fonction de décalage, de faire appel à la fonction(la liaison qui s'est passé au moment de l'exécution)
Assemblée de 64 est source de confusion, la plupart des programmeurs c++, mais si tout voudrais discuter de alors bienvenue
OriginalL'auteur Ajay yadav