Académique Documents
Professionnel Documents
Culture Documents
sur fonctions
Par Matthieu Schaller (Nanoc)
www.openclassrooms.com
2/12
Sommaire
Sommaire ........................................................................................................................................... 2
[C++] Les pointeurs sur fonctions ...................................................................................................... 3
Choisir une fonction ........................................................................................................................................................... 3
Le minimum d'une fonction ......................................................................................................................................................................................... 3
Utiliser un type numr ? .......................................................................................................................................................................................... 4
5
6
7
7
www.openclassrooms.com
Sommaire
3/12
Par
{ return x*x;}
return 1/x;}
{ return sqrt(x);}
{ return exp(x);}
www.openclassrooms.com
4/12
return min;
//..
L'algorithme de calcul du minimum n'est pas bien malin, mais ce n'est pas ce qui nous proccupe ici.
Chaque fois que l'on voudrait calculer le minimum d'une autre fonction, il faudrait d-commenter la ligne concerne et recompiler
le programme. Ceci n'est videmment pas satisfaisant, il serait beaucoup mieux de pouvoir passer un argument la fonction
permettant de savoir de quelle fonction
, elle doit chercher le minimum.
return min;
//..
Ce code est mieux que le prcdent, il n'y a plus besoin de recompiler chaque fois que l'on veut changer la fonction valuer.
Cependant, ce n'est toujours pas trs pratique. Si l'on veut ajouter une nouvelle fonction, il faut modifier l'enum et surtout, il faut
www.openclassrooms.com
5/12
modifier le code de la fonction minimum, ce qui videmment une trs mauvaise chose. On ne devrait pas avoir modifier la
fonction minimum chaque fois qu'on ajoute une nouvelle fonction mathmatique.
La meilleure chose serait de pouvoir donner directement minimum, la fonction que l'on souhaite valuer. Et si je vous en parle,
c'est que c'est faisable (vous en doutiez ?
) et mme de manire lgante.
int (*ptr)(int,double) n'est pas quivalent int (*ptr)(double,int), l'ordre des arguments joue
un rle. De mme void (*ptr)(double) n'est pas quivalent void (*ptr)(int), mme si les
transformations de int en double sont automatiques.
Un pointeur sur fonction est un type comme un autre. Vous pouvez donc tout fait crer un tableau de pointeurs sur
fonctions, un std::vector<> de pointeurs sur fonctions ou mme un pointeur sur pointeur de fonction.
Bon c'est bien joli tout a, mais notre pointeur pour le moment ne pointe sur rien (ou en tout cas pas sur une fonction que vous
www.openclassrooms.com
6/12
//...
Ce code est tout fait correct, cependant les crateurs du C++ ont voulu simplifier ceci et ont dcid qu'il n'tait pas ncessaire
d'utiliser l'oprateur &. Le code suivant revient donc au mme:
Code : C++ - Affectation d'un pointeur par la bonne mthode
#include <string>
using namespace std;
int fonction(double a,string phrase)
{
//blablabla
}
int main()
{
int (*monPointeur)(double,string);
fonction
monPointeur = fonction;
//Et on le fait pointer sur "fonction"
// Notez l'absence du '&' !!
}
//...
Et c'est cette dernire mthode qui est utilise par tous les programmeurs. Il n'est pas faux d'utiliser le &, mais personne ne le fait.
Puisque la notation est assez explicite sans, il n'est pas ncessaire pour le compilateur et pour les programmeurs d'ajouter le &.
Il est tout fait possible d'affecter un pointeur directement l'initialisation. Le code serait alors:
void (*pointeur)(int) = fonction;
www.openclassrooms.com
7/12
int main()
{
int (*ptr) (int,int); //Un joli pointeur
ptr = maximum;
Les lignes 12 et 15 sont tout fait quivalentes au niveau du programme gnr. Mais comme prcdemment, personne n'utilise
la version avec *. On peut donc dduire la rgle suivante:
On utilise un pointeur sur fonction de la mme manire qu'on utilise la fonction pointe.
www.openclassrooms.com
8/12
return min;
int main()
{
cout <<
endl;
cout <<
cout <<
cout <<
cout <<
cout <<
------
int reponse;
cin >> reponse;
Fonction monPointeur; //On declare un pointeur sur fonction
switch(reponse){ //Et on
choisie
case 1: monPointeur =
case 2: monPointeur =
case 3: monPointeur =
case 4: monPointeur =
case 5: monPointeur =
fonctions de cmath !
}
return 0;
//ae
//re-ae mais dj mieux
www.openclassrooms.com
9/12
Il y a deux erreurs possibles. La premire consiste se tromper dans le nom de la fonction. Elle ne se nomme pas fonction mais
A::fonction, car elle fait partie de la classe A.
La deuxime erreur est beaucoup plus subtile. En effet une fonction membre reoit en ralit implicitement un argument
supplmentaire, une sorte de pointeur this sur l'objet qui appelle la fonction ! Il faut donc d'une certaine manire en tenir compte
lors de la dclaration du pointeur, c'est pour cela qu'il faut mettre A:: devant le nom du pointeur lors de sa dclaration. La dernire
ligne du code est donc correcte. Remarquez qu'il est ncessaire dans ce cas d'utiliser l'oprateur &.
S'il s'agit d'une fonction membre static, cette deuxime rgle ne s'applique pas. En effet une fonction statique ne reoit
pas de pointeur sur un objet en argument "cach" puisqu'elle peut tre appele sans objet.
Cependant, un autre problme survient rapidement. Comment utiliser le pointeur puisqu'il ncessite un objet ?
Cela se fait de la manire suivante:
Code : C++ - Utilisation d'un pointeur sur fonction membre
class A{
public:
int fonction(int a);
//...
};
int A::fonction(int a){return a*a;}
int main()
{
int (A::*ptr)(int) = &A::fonction;
la fonction membre
A instance;
return 0;
Pfffou...
En effet, les pointeurs sur fonctions membres ne sont pas trs digestes utiliser.
Vous remarquerez quand mme l'utilisation obligatoire de l' oprateur* et la prsence indispensable des parenthses.
www.openclassrooms.com
10/12
class A{
public:
int fonction(int x)
{
return x*x;
}
//...
};
typedef int (A::*APointeurFonction)(int)
En faisant a, on peut utiliser ApointeurFonction la place de la dclaration habituelle prsente dans l'exemple prcdent, ce qui
donne:
Code : C++
int main()
{
APointeurFonction ptr = &A::fonction;
ce qui simplifie la notation
A instance;
return 0;
return 0;
L'utilisation de la macro simplifie donc grandement le travail puisqu'on a eu besoin de rflchir qu'une seule fois la position des
* et des parenthses.
www.openclassrooms.com
11/12
Je me rpte, mais c'est important. Les macros sont gnralement viter en C++. Ici, c'est un des rares cas o leur
emploi se justifie.
Voil, c'est tout ce qu'il y avait dire sur ce petit sujet. Mais je ne pense pas que vous aurez besoin souvent des pointeurs de
fonctions membres.
Comme dj dit dans l'introduction, il est plus simple d'utiliser des foncteurs, la "version C++" du pointeur de fonction qui permet
de faire les choses plus facilement.
Merci Chlab_lak pour avoir propos l'utilisation de la macro.
Partager
Ce tutoriel a t corrig par les zCorrecteurs.
www.openclassrooms.com