Quelle est la différence entre la distribution dynamique et la fin de la liaison en C++?
J'ai lu récemment sur la répartition Dynamique sur Wikipédia et ne pouvait pas comprendre la différence entre la dynamique de l'expédition et de la liaison tardive en C++.
Lors de chacune de ces mécanismes est-il utilisé?
La citation exacte de Wikipedia:
Dynamique de l'expédition est différente de la liaison tardive (aussi connu comme la liaison dynamique). Dans le contexte de la sélection d'une opération, la liaison se réfère au processus d'associer un nom à une opération. Envoi désigne le choix d'une mise en œuvre de l'opération après que vous avez décidé de l'opération pour laquelle un nom se réfère. Avec répartition dynamique, le nom peut être lié à un polymorphe de l'opération au moment de la compilation, mais la mise en œuvre de ne pas être choisi jusqu'à l'exécution (c'est de cette façon dynamique envoi fonctionne en C++). Cependant, la liaison tardive implique dynamique de dispatching, puisque vous ne pouvez pas choisir la mise en œuvre d'un polymorphe de l'opération pour sélectionner jusqu'à ce que vous avez sélectionné l'opération que le nom fait référence à l'.
- C'est une bonne question et peut-être mieux si vous mentionnez les liens que vous avez lus.
Vous devez vous connecter pour publier un commentaire.
Une assez bonne réponse à cette question est effectivement intégrés dans une question sur la fin de vs au début de liaison sur programmers.stackexchange.com.
En bref, la liaison tardive se réfère à la objetcôté d'un eval, répartition dynamique se réfère à la fonctionnelle de côté. À la fin de la liaison de la type d'une variable est la variante au moment de l'exécution. Dans la dynamique de régulation, la fonction ou sous-routine exécutée est la variante.
En C++, nous n'avons pas vraiment la liaison tardive, car le type est connu (pas nécessairement la fin de la hiérarchie d'héritage, mais au moins une base formelle de la classe ou de l'interface). Mais nous ne dynamique d'expédition via des méthodes virtuelles et le polymorphisme.
Le meilleur exemple que je peux vous offrir pour la fin de la liaison est de type "objet" dans Visual Basic. L'environnement d'exécution ne tous les la fin de liaison de levage lourd pour vous.
Le compilateur fait le code approprié du contexte d'exécution pour l'exécution-moteur pour effectuer un nommé de recherche de la méthode appelée
DoSomething
, et si elle est découverte à l'correctement correspondance des paramètres, de l'exécution de l'appel sous-jacent. En réalité, quelque chose sur le type de l'objet est connue (elle hérite deIDispatch
et prend en chargeGetIDsOfNames()
, etc). mais aussi loin que la langue est concerné par la type de la variable est complètement inconnu au moment de la compilation, et il n'a aucune idée de siDoSomething
est même une méthode pour quelqueobj
fait est jusqu'à l'exécution atteint le point d'exécution.Je vais pas la peine de dumping, un C + + interface virtuelle et al, comme je suis sûr que vous savez déjà à quoi ils ressemblent. J'espère qu'il est évident que le langage C++ ne peuvent tout simplement pas faire cela. Il est fortement typées. Il peut (et, bien sûr) de faire la distribution dynamique via le polymorphe méthode virtuelle de la fonctionnalité.
DoSomthing
. Ne pas confondre le langue avec le exécution. J'ai essayé de faire ce clair, mais honnêtement, je suis moi-même seulement de façon marginale satisfait de la description. Sur le C++ côté vous aurait du code de la toutes les dynamiques vous-même viaIDispatch
, et même alors, le langue sait quelque chose de l'objet (il prend en chargeIDispatch
etc.).La liaison tardive est l'appel d'une méthode par nom lors de l'exécution.
Vous n'avez pas vraiment ce en c++, sauf pour l'importation de méthodes à partir d'une DLL.
Un exemple de cela pourrait être: GetProcAddress()
Avec répartition dynamique, le compilateur a suffisamment d'informations pour appeler la bonne mise en œuvre de la méthode. Ceci est habituellement fait par la création d'un table virtuelle.
La lien lui-même expliqué la différence:
et
Mais ils sont essentiellement égaux en C++, vous pouvez faire une répartition dynamique par des fonctions virtuelles et les vtables.
En C++, les deux sont les mêmes.
En C++, il existe deux types de liaison:
De liaison dynamique, puisqu'il est fait au moment de l'exécution, est aussi appelé la liaison tardive et statique de la liaison est parfois appelé comme la liaison anticipée.
Dynamiques à l'aide de liaison, C++ prend en charge l'exécution de polymorphisme à travers virtuel fonctions (ou pointeurs de fonction), et à l'aide de statique de liaison, tous les autres des appels de fonctions sont résolus.
Liaison désigne le processus d'associer un nom à une opération.
la chose principale ici est la fonction de ces paramètres décide de la fonction à appeler lors de l'exécution
Envoi désigne le choix d'une mise en œuvre de l'opération après que vous avez décidé de l'opération pour laquelle un nom se réfère.
envoi de contrôle pour que selon le paramètre match
http://en.wikipedia.org/wiki/Dynamic_dispatch
espère que cela vous aider à
Laissez-moi vous donner un exemple des différences parce qu'ils ne sont PAS les mêmes. Oui, répartition dynamique vous permet de choisir la méthode appropriée lorsque vous faites référence à un objet par une super-classe, mais que la magie est très spécifique à cette hiérarchie de classe, et que vous avez à faire certaines déclarations dans la classe de base pour le faire fonctionner (méthodes abstraites remplir les vtables depuis que l'indice de la méthode dans le tableau cant changement entre les types spécifiques). Ainsi, vous pouvez appeler des méthodes dans Tabby et le Lion et le Tigre tous par un générique Chat pointeur et même avoir des tableaux de Chats rempli avec les Lions et les Tigres et les Tabbys. Il sait ce qu' index ces méthodes font référence à l'objet qui est vtable au moment de la compilation (statique/liaison précoce), même si la méthode est sélectionné au moment de l'exécution (dynamique de l'expédition).
Maintenant, permet de mettre en œuvre un tableau qui contient des Lions et des Tigres et des Ours! ((Oh Mon Dieu!)). En supposant que nous n'avons pas une classe de base appelée Animal, en C++, vous allez avoir beaucoup de travail à faire parce que le compilateur ne va pas vous permettre de faire toute la distribution dynamique sans une classe de base commune. Les indices pour les vtables besoin de faire correspondre, et qui ne peut être fait entre unreleated classes. Vous auriez besoin d'avoir une vtable assez grand pour contenir les méthodes virtuelles de toutes les classes dans le système. Les programmeurs C++ est rare de voir cela comme une limitation, car vous avez été formé à penser d'une certaine manière au sujet de la conception des classes. Je ne dis pas que son meilleur ou pour le pire.
Avec la liaison tardive, au moment de l'exécution prend en charge ce sans une classe de base commune. Il y a normalement une table de hachage utilisé pour trouver des méthodes dans les classes avec un système de cache utilisé dans le répartiteur. Où en C++, le compilateur sait tous les types. Dans une fin liée à la langue, les objets eux-mêmes connaître leur type (ce n'est pas sans type, les objets eux-mêmes savent exactement qui ils sont dans la plupart des cas). Cela signifie que je peux avoir des tableaux de plusieurs types d'objets si je veux (Lions et des Tigres et des Ours). Et vous pouvez mettre en œuvre le transfert de messages et de prototypage (permet de comportements à être changé par objet sans changer la classe) et toutes sortes d'autres choses d'une manière beaucoup plus souple et le plomb à moins de code de frais généraux que dans les langues qui ne prennent pas en charge la liaison tardive.
Jamais programme Android et utiliser findViewById()? Vous avez presque toujours en fin de coulée, le résultat à obtenir le bon type, et le casting est essentiellement mentir pour le compilateur et de renoncer à tous les types statiques-la vérification de la bonté qui est censé prendre des langages statiques supérieur. Bien sûr, vous pourriez avoir findTextViewById(), findEditTextById(), et un million d'autres, de sorte que votre retour types de match, mais qui est en train de jeter le polymorphisme de la fenêtre; sans doute l'ensemble de la base de la programmation orientée objet. Un retard lié à la langue serait probablement vous permettre tout simplement de l'indice par un ID, et la traiter comme une table de hachage et de ne pas garde à ce que le type était en cours d'indexation, ni retournés.
Voici un autre exemple. Disons que vous avez votre Lion classe et de son comportement par défaut est de vous manger quand vous le voyez. En C++, si vous voulez avoir un seul "formés" le lion, vous devez faire une nouvelle sous-classe. Prototypage vous permet de modifier simplement l'une ou les deux méthodes de Lion qui a besoin d'être changé. C'est la classe et le genre ne changent pas. C++ ne peut pas le faire. Ceci est important car lorsque vous avez un nouveau "AfricanSpottedLion" qui hérite de Lion, vous pouvez vous entraîner aussi. Le prototypage ne change pas la structure de classe de sorte qu'il peut être étendu. Normalement, c'est la façon dont ces langues de traiter les questions qui exigent normalement l'héritage multiple, ou peut-être l'héritage multiple est la façon dont vous gérez un manque de prototypage.
Pour info, Objective-C est C avec SmallTalk du message en passant ajoutée et SmallTalk est à l'origine de la programmation orientée objet, et les deux sont en retard lié avec toutes les caractéristiques ci-dessus et plus. Tardive des langues peut être un peu plus lent à partir d'un micro-niveau point de vue, mais il peut souvent permettre le code structuré d'une manière qui est plus efficace au niveau macro-économique, et tout se résume à la préférence.
Étant donné que verbeux définition de Wikipedia, je serais tenté de classer la distribution dynamique comme la fin de la liaison de C++
La liaison tardive au lieu de cela, pour Wikipédia, semble signifier pointeur de membre envoi de C++
où la sélection de qu'est-ce que l'opération invoquée (et pas seulement de la mise en œuvre) se fait au moment de l'exécution.
En C++ de la littérature cependant
late binding
est normalement utilisé pour ce que Wikipédia appels répartition dynamique.Répartition dynamique est ce qui arrive lorsque vous utilisez le
virtual
mot-clé en C++. Ainsi, par exemple:imprime
3
, parce que la méthode a été dynamiquement distribué. La norme C++ est très prudent pas pour spécifier comment exactement ce qui se passe en coulisses, mais chaque compilateur sous le soleil est-il de la même manière. Ils créent un tableau de pointeurs de fonction pour chaque type polymorphe (appelé le table virtuelle ou vtable), et lorsque vous appelez une méthode virtuelle, la "vraie" méthode est recherchée dans la vtable, et cette version est appelée. De sorte que vous pouvez l'imagerie quelque chose comme ce pseudo-code:De cette façon, le compilateur peut être sûr que d'une méthode avec une signature existe au moment de la compilation. Cependant, au moment de l'exécution, l'appel peut être envoyé par la vtable à une fonction différente. Les appels à des fonctions virtuelles sont un tout petit peu plus lent que les non-virtuel les appels, en raison de la supplémentaire d'indirection étape.
D'autre part, ma compréhension du terme la liaison tardive est que le pointeur de fonction est regardé par nom au moment de l'exécution, à partir d'une table de hachage ou quelque chose de similaire. C'est la façon dont les choses sont faites en Python, JavaScript et (si ma mémoire est bonne) Objective-C. Cela permet d'ajouter de nouvelles méthodes à une classe au moment de l'exécution, qui ne peuvent pas directement être fait en C++. Ceci est particulièrement utile pour la mise en œuvre de choses comme mixin. Cependant, l'inconvénient est que le temps d'exécution de recherche est généralement nettement plus lent que même un appel virtuel en C++, et le compilateur n'est pas en mesure d'effectuer tout type de compilation vérification pour le nouvellement ajouté méthodes.
Je suppose que le sens, c'est quand vous avez deux classes B,C hérite de la même père de classe A. ainsi, pointeur du père (type A) peut demander à chacun des types de fils. Le compilateur ne peut pas savoir de quel type est titulaire dans le pointeur dans certains temps, car elle peut changer au cours de l'exécution du programme.
Il y a des fonctions spéciales pour déterminer quel est le type d'objet à un moment donné. comme
instanceof
en java, ou parif(typeid(b) == typeid(A))...
en c++.Ce question pourrait vous aider.
Répartition dynamique se réfère généralement à la répartition multiple.
Considérons l'exemple ci-dessous. J'espère que ça peut vous aider.
Prenons le cas de la ci-dessous.
Il va appeler
function1
prendreBase2*
pasDerived2*
. Cela est dû au manque de dynamique de la répartition multiple.La liaison tardive est l'un des mécanisme de mise en œuvre dynamique unique de l'expédition.
En C++, les deux
dynamic dispatch
etlate binding
est le même. Fondamentalement, la valeur d'un objet unique détermine le morceau de code invoquée au moment de l'exécution. Dans des langages comme C++ et java répartition dynamique est plus particulièrement dynamique unique d'expédition qui fonctionne comme mentionné ci-dessus. Dans ce cas, puisque la liaison se produit au moment de l'exécution, il est aussi appelélate binding
. Des langages comme smalltalk permettre dynamique de la répartition multiple dans lequel le moteur d'exécution de la méthode est choisie au moment de l'exécution fondée sur l'identité ou les valeurs de plus d'un objet.En C++ nous n'avons pas vraiment d'avoir une liaison tardive, car le type d'informations est connu. Ainsi, dans le C++ ou Java contexte, la dynamique de l'expédition et de la liaison tardive sont les mêmes. Réel/entièrement la liaison tardive, je pense, dans des langages comme python, qui est une méthode à base de recherche plutôt que de type de base.