Dès qu’en C++ je dois faire des pointeurs sur fonction membre (ou méthode) d’une classe c’est toujours la même chose : je ne me souviens jamais de l’enfer syntaxique que constitue la déclaration, l’assignation, et l’utilisation d’un pointeur sur fonction membre ! >:(

Combien de parenthèses ? Où ? Quand ? Comment ? Et en plus le nombre / l’emplacement des parenthèses change entre la déclaration et l’appel…
Bref c’est pour ça que je m’écris, ici, définitivement, et aussi pour quiconque à qui ça pourrait servir, ce mémo :
-
Déclaration.
Un pointeur sur fonction normal se déclarerait de la façon suivante :
1 |
int (*fptr)(bool, int) |
fptr est ici un pointeur sur une fonction prenant en paramètre un booléen et un entier, et renvoyant un entier. En C++, le fait qu’une fonction appartient à une classe se décrit dans le code avec l’opérateur d’appartenance « :: », précédé du nom de ladite classe. La méthode « leDauphin » de la classe Echo s’écrirait donc Echo::leDauphin(…). Ainsi, pour déclarer un pointeur sur une fonction membre de la classe Echo, qui retourne un int et prend en paramètre un booléen et un int, on écrira par exemple :
1 |
int (Echo::*fptr)(bool, int) |
Bien pratique quand on a des fonctions d’analyse, ou des setters, qui marchent à peu près pareil, et qui permettent de factoriser du code de façon fabuleuse (comme je le fais actuellement, mais c’est une autre histoire).
-
Assignation.
C’est là que le fun commence : en général un pointeur sur fonction c’est plus utile quand il pointe vers une fonction. Et là, pour setter la valeur du pointeur, attention les yeux : PLUS DE PARENTHÈSES !
1 |
int (Echo::*fptr)(bool, int) = &Echo::leDauphin; |
-
Utilisation.
Un pointeur sur méthode, ou fonction membre, comme son nom l’indique, permet de lancer une fonction faisant partie d’un objet. Il ne rime donc à rien de vouloir l’appeler sans un objet du type correspondant. Et c’est là le summum, le top, le nec plus ultra, car on va mélanger plein de symboles syntaxiques : le point, la parenthèse, l’étoile, bref autant de trucs qui font qu’on a vite fait de se tromper… En bref, l’appel à un pointeur sur fonction membre ça donne ça :
1 |
(echo.*fptr)(true |