Quel est le point de pointeurs de fonction?
J'ai du mal à voir l'utilité des pointeurs de fonction. J'imagine que ça peut être utile dans certains cas (ils existent, après tout), mais je ne peux pas penser à un cas où il est mieux ou inévitable d'utiliser un pointeur de fonction.
Pourriez-vous donner quelques exemple de bonne utilisation de pointeurs de fonction (en C ou C++)?
- Vous pouvez trouver tout à fait un peu de discussion sur les pointeurs de fonction dans ceci concerne, DONC, la question.
- double possible de stackoverflow.com/questions/840501/...
- Pas vraiment. "Comment une TÉLÉ?" est tout à fait une autre question que celle de "Que dois-je faire avec un TÉLÉVISEUR?"
- En C++, vous allez probablement utiliser un foncteur (en.wikipedia.org/wiki/Function_object#In_C_and_C.2B.2B) à la place.
- Dans les vieux jours sombres où C++ est compilé à C, vous pouvez réellement voir comment les méthodes virtuelles sont mises en œuvre - ouais, avec des pointeurs de fonction.
- +1 pour le jeu de mots dans le titre.
- Très essentielle lorsque vous voulez utiliser le C++ avec un managed C++ ou C#, c'est à dire: les délégués et les rappels
- Quel est le point de non-pointeurs de fonction?
Vous devez vous connecter pour publier un commentaire.
La plupart des exemples se résument à rappels: Vous appelez une fonction
f()
en passant l'adresse d'une autre fonctiong()
, etf()
appelsg()
pour certains tâche spécifique. Si vous passerf()
l'adresse deh()
au lieu de cela, puisf()
neh()
à la place.Fondamentalement, c'est une façon de paramétrer une fonction: une partie de son comportement n'est pas codée en dur dans
f()
, mais dans la fonction de rappel. Les appelants peuvent fairef()
se comportent différemment en passant par les différentes fonctions de rappel. Un classique estqsort()
de la bibliothèque C standard qui prend son critère de tri comme un pointeur vers une fonction de comparaison.En C++, cela se fait souvent à l'aide de fonction des objets (également appelé foncteurs). Ce sont des objets que la surcharge de l'opérateur d'appel de fonction, de sorte que vous pouvez les appeler comme si elles étaient une fonction. Exemple:
L'idée derrière cela est que, contrairement à un pointeur de fonction, un objet de fonction peut porter non seulement un algorithme, mais également des données:
Un autre avantage est qu'il est parfois plus facile de l'inclure des appels à la fonction des objets que des appels par le biais de pointeurs de fonction. C'est une des raisons pourquoi le tri en C++ est parfois plus rapide que le tri de C.
Bien, en général, je les utiliser (par des professionnels) dans sauter les tables (voir aussi cette question StackOverflow).
Sauter tables sont souvent (mais pas exclusivement) utilisé dans des machines à états finis pour les rendre pilotés par les données. Au lieu de imbriquée switch/case
vous pouvez faire un tableau 2d ou des pointeurs de fonction et il suffit d'appeler
handleEvent[state][event]
Exemples:
les modèles (comme la Stratégie, de l'Observateur)
Le "classique" exemple pour l'utilité des pointeurs de fonction est la bibliothèque C
qsort()
fonction, qui met en œuvre un Tri Rapide. Afin d'être universelle pour toute et toutes les structures de données de l'utilisateur peuvent venir avec, on prend un couple de pointeurs void à triable de données et un pointeur vers une fonction qui sait comment comparer deux éléments de ces structures de données. Cela nous permet de créer notre fonction de choix pour le travail, et en fait même permet de choisir la fonction de comparaison au moment de l'exécution, par exemple pour le tri croissant ou décroissant.bsearch
!Je vais aller à contre-courant ici.
En C, les pointeurs de fonction sont la seule façon de mettre en œuvre la personnalisation, car il n'est pas OO.
En C++, vous pouvez utiliser des pointeurs de fonction ou de foncteurs (objets de fonction) pour le même résultat.
Foncteurs ont un certain nombre d'avantages par rapport aux premières pointeurs de fonction, en raison de leur objet, la nature, notamment:
operator()
lambda
etbind
)Personnellement, je préfère les foncteurs de pointeurs de fonction (en dépit du code réutilisable), principalement parce que la syntaxe des pointeurs de fonction peut facilement s'arracher les cheveux (à partir de la Pointeur De Fonction Tutoriel):
La seule fois où j'ai vu des pointeurs de fonction utilisé lorsque les foncteurs ne pouvaient pas été dans le coup de pouce.Esprit. Ils ont totalement abusé de la syntaxe de transmettre un nombre arbitraire de paramètres que d'un seul paramètre du modèle.
Mais depuis variadic templates et les lambdas sont autour du coin, je ne suis pas sûr que nous allons utiliser des pointeurs de fonction en C++ pur code pour longtemps.
bind
oufunction
vous utiliser des pointeurs de fonction. C'est comme de dire que nous n'utilisons pas de pointeurs en C++ parce que nous utilisons des pointeurs intelligents. De toute façon, je suis tatillon.En C, l'utilisation classique est la la fonction qsort, où le quatrième paramètre est pointeur vers une fonction à utiliser pour effectuer la commande dans le genre. En C++, on aurait tendance à utiliser les foncteurs (des objets qui ressemblent à des fonctions) pour ce genre de chose.
bsearch
!D'accord avec tout ce qui précède, plus....
Lorsque vous chargez une dll dynamiquement à l'exécution, vous aurez besoin de pointeurs de fonction pour appeler les fonctions.
J'ai utilisé des pointeurs de fonction récemment de créer une couche d'abstraction.
J'ai un programme écrit en pur C qui s'exécute sur les systèmes embarqués. Il prend en charge matérielles multiples variantes. En fonction du matériel, je suis en cours d'exécution, il doit appeler les différentes versions de certaines fonctions.
Pendant la phase d'initialisation, le programme des chiffres de ce matériel, il est en cours d'exécution sur et remplit les pointeurs de fonction. L'ensemble de la hausse du niveau des routines dans le programme à appeler les fonctions référencées par des pointeurs. Je peux ajouter la prise en charge de nouveau matériel variantes sans toucher au plus haut niveau de routines.
J'ai utilisé le switch/case instructions pour choisir la bonne fonction des versions, mais cela est devenu impossible que le programme s'est étendu à l'appui de plus en plus de matériel variantes. J'ai dû ajouter de cas relevés dans tous les sens.
J'ai aussi essayé intermédiaire de la fonction de couches de comprendre la fonction à utiliser, mais ils n'ont pas beaucoup d'aide. J'ai toujours eu à mettre à jour les cas relevés dans plusieurs endroits à chaque fois que nous avons ajouté une nouvelle variante. Avec les pointeurs de fonction, je n'ai qu'à changer la fonction d'initialisation.
Comme Riche dit ci-dessus, il est très habituel pour les pointeurs de fonctions dans Windows pour faire référence à une adresse qui stocke la fonction.
Lorsque vous la programmation en
C language
sur la plateforme Windows, vous avez la charge, le fichier DLL dans la mémoire primaire(à l'aide deLoadLibrary
) et à utiliser les fonctions stockées dans la DLL, vous devez créer des pointeurs de fonctions et de point à cette adresse (à l'aide deGetProcAddress
).Références:
LoadLibrary
GetProcAddress
Pointeurs de fonction peut être utilisé en C pour créer une interface à l'encontre de qui de programme. En fonction de la fonctionnalité spécifique qui est nécessaire à l'exécution, d'une mise en œuvre différente peut être assignée à la fonction de pointeur.
Mon utilisation principale d'entre elles a été RAPPELS: lorsque vous avez besoin pour enregistrer des informations sur une fonction de appeler plus tard.
Dire que vous êtes en train de rédiger Bomberman. 5 secondes après que la personne laisse tomber la bombe, elle doit exploser (la
explode()
fonction).Maintenant, il y a 2 façons de le faire. Un moyen est de "sonder" toutes les bombes sur l'écran pour voir si ils sont prêts à exploser dans la boucle principale.
Une autre façon est d'attacher un rappel de votre horloge de système. Quand une bombe est planté, vous ajouter un rappel à faire appel à la bombe.explode() quand le moment est venu.
Ici
callback.function()
peut être toute fonction, parce que c'est un pointeur de fonction.Pour les langages à objets, pour effectuer polymorphes appels en coulisses (ceci est également valable pour C jusqu'à un certain point, je suppose).
En outre, ils sont très utiles pour injecter des comportements différents à une autre fonction (foo) au moment de l'exécution. Que fait la fonction foo fonction d'ordre supérieur. En plus de la flexibilité, qui fait de la foo code plus lisible, car il vous permet d'extraire de la logique supplémentaire de "if-else" hors de lui.
Il permet beaucoup d'autres choses utiles en Python, comme les générateurs, fermetures etc.
Un point de vue différent, en plus d'autres bonnes réponses ici:
Dans C, il existe seulement des pointeurs de fonction, il n'y a pas toutes les fonctions.
Je veux dire, vous écrire des fonctions, mais tu ne peux pas manipuler fonctions. Il n'y a aucun moment de l'exécution de la représentation d'une fonction en tant que telle. Vous ne pouvez même pas l'appeler "fonction". Lorsque vous écrivez:
ce que vous êtes en train de dire est "effectuer un appel à l'
my_function
pointeur avec l'argument spécifié". Vous faites un appel via un pointeur de fonction. Cette la carie de pointeur de fonction signifie que les commandes suivantes sont équivalentes aux précédentes appel de la fonction:et ainsi de suite (merci @LuuVinhPhuc).
Donc, vous êtes déjà à l'aide de pointeurs de fonction en tant que valeurs. Évidemment, vous voulez avoir des variables pour ces valeurs - et c'est là où toutes les autres utilisations metion venir: Polymorphisme/personnalisation (comme dans qsort), les rappels, sauter tables etc.
En C++, les choses sont un peu plus compliquées, puisque nous avons des lambdas, et les objets de
operator()
, et même unstd::function
classe, mais le principe est toujours essentiellement la même.(&my_function)(my_arg)
,(*my_function)(my_arg)
,(**my_function)(my_arg)
,(&**my_function)(my_arg)
,(***my_function)(my_arg)
... parce que les fonctions de décroissance à des pointeurs de fonctionUtilisation de pointeur de fonction
À fonction d'appel dynamiquement basée sur la saisie de l'utilisateur.
Par la création d'une carte de la chaîne et de pointeur de fonction dans ce cas.
De cette façon, nous avons utilisé la fonction de pointeur dans la réalité de notre société.
Vous pouvez écrire " n " numéro de fonction et de les appeler à l'aide de cette méthode.
De SORTIE:
J'utilise des pointeurs de fonction largement, pour l'émulation de microprocesseurs qui ont 1 octet opcodes. Un tableau de 256 pointeurs de fonction est le moyen naturel de le mettre en œuvre.
Une utilisation de pointeur de fonction pourrait être là où on ne peut pas vouloir modifier le code où la fonction est appelé (à savoir l'appel peut être conditionnelle et sous différentes conditions, nous avons besoin de faire différents types de traitement).
Ici, les pointeurs de fonction sont très pratique, car nous n'avons pas besoin de modifier le code à l'endroit où la fonction est appelé. Nous avons simplement appeler la fonction en utilisant le pointeur de fonction avec les arguments appropriés.
Le pointeur de fonction peut être fait à point pour les différentes fonctions de manière conditionnelle. (Cela peut être fait quelque part au cours de la phase d'initialisation). En outre, le modèle ci-dessus est très utile, si nous ne sommes pas en mesure de modifier le code où il est appelé (supposons que c'est une bibliothèque d'API, nous ne pouvons pas modifier). L'API utilise un pointeur de fonction pour appeler l'appropriées en fonction définie par l'utilisateur.