Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1431 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [Résolu] Appeler une fonction avec comme paramètre la fonction d'appel

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Résolu] Appeler une fonction avec comme paramètre la fonction d'appel

n°1576706
SkippyleGr​andGourou
Posté le 19-06-2007 à 11:56:00  profilanswer
 

Salut,
 
Est-ce qu'il y a un moyen de passer en argument d'une fonction B la fonction A (ou son nom) qui l'appelle ? J'ai un programme qui affiche (enfin qui peut potentiellement afficher) plein de warnings et je voudrais les regrouper dans une fonction warn, faire un truc du genre :

Code :
  1. maFonction:
  2.      ...
  3.      si [attention] Warn("je suis appelé par maFonction" );
  4.      ...
  5. Warn:
  6.      si je suis appelé par maFonction, affiche warning 1
  7.      si je suis appelé par monOtreFonction, affiche warning 2
  8.      ...


 
C'est complètement inutile, je sais, mais ça me semble plus propre parce que :
1- Tous les avertissements sont au même endroit, pratique si je veux changer leur format (ou leur langue, bien que ça n'arrivera pas)  :o  
2- Ça m'évite d'avoir plein de cout tout moches en plein milieu du code...  
3- Si c'est possible j'apprend quelque chose, donc ça me fait progresser un peu :D
 
Alors ? Verdict ?
 
Merci.
 
PS : Je sais pas trop comment formuler mon problème dans google, alors soyez indulgents...


Message édité par SkippyleGrandGourou le 20-06-2007 à 15:24:17
mood
Publicité
Posté le 19-06-2007 à 11:56:00  profilanswer
 

n°1576728
deadalnix
Posté le 19-06-2007 à 12:40:13  profilanswer
 
n°1576800
SkippyleGr​andGourou
Posté le 19-06-2007 à 14:47:46  profilanswer
 

Oui. Je m'attendais plus à un truc générique qui aurait été équivalent à "this", mais c'est vrai que je pourrais tout simplement donner en argument de Warn() un pointeur de fonction adapté à chaque fois. Mes fonctions ayant un type différent, je serais obligé de les transtyper mais c'est pas bien grave puisque seul le nom m'intéresse, et ensuite (le déclic à eu lieu en parcourant un de tes liens (bien qu'il n'en parle absolument pas), donc merci ;) ) faire un mapping entre la fonction et le warning.
 
Malheureusement, je n'y avais pas pensé plus tôt mais mes fonctions peuvent contenir plusieurs avertissements... Évidemment je peux mettre un deuxième argument à Warn(), mais au lieu d'améliorer la lisibilité (mon but initial), je pense que je m'engage dans un truc qui va rendre mon code enore bien plus illisible qu'il ne l'est déjà.
 
J'abandonne donc l'idée pour l'instant.
 
Merci quand même. ;)

n°1576804
franceso
Posté le 19-06-2007 à 14:57:06  profilanswer
 

SkippyleGrandGourou a écrit :

Oui. Je m'attendais plus à un truc générique qui aurait été équivalent à "this", mais c'est vrai que je pourrais tout simplement donner en argument de Warn() un pointeur de fonction adapté à chaque fois. Mes fonctions ayant un type différent, je serais obligé de les transtyper mais c'est pas bien grave puisque seul le nom m'intéresse, et ensuite (le déclic à eu lieu en parcourant un de tes liens (bien qu'il n'en parle absolument pas), donc merci ;) ) faire un mapping entre la fonction et le warning.

Dans ce cas là, plutôt que de t'embêter avec des pointeurs de fonctions transtypés, pourquoi ne pas passer à ta fonction tout simplement un identifiant (par exemple de type int) qui caractérise l'erreur :??:


---------------
TriScale innov
n°1576813
SkippyleGr​andGourou
Posté le 19-06-2007 à 15:12:33  profilanswer
 

franceso a écrit :

Dans ce cas là, plutôt que de t'embêter avec des pointeurs de fonctions transtypés, pourquoi ne pas passer à ta fonction tout simplement un identifiant (par exemple de type int) qui caractérise l'erreur :??:

Je sais pas, ça me semble trop confus, au moins dans le cas des entiers : il faudrait à chaque fois aller voir la liste des erreurs pour voir le message, faire attention à ce que l'entier ne soit pas déjà pris, ne pas se tromper d'entier... À la rigueur une chaine de caractères, c'est vrai que ça serait aussi (et même plus) simple que des pointeurs de fonction adaptés à chaque fonction (enfin je me comprends...), mais je trouve pas ça très élégant... C'est pour ça qu'à la base j'attendais un truc équivalent à "this" pour les fonctions, beaucoup plus générique.

 

Je vais y réfléchir.  :)

 

PS : Un autre argument imparable est que j'ai un esprit tordu... ;)


Message édité par SkippyleGrandGourou le 19-06-2007 à 15:13:20
n°1576958
deadalnix
Posté le 19-06-2007 à 17:39:25  profilanswer
 

Avec une batterie de define tu peux faire un truc tres clair rien qu'en apssant des int franceso a raison.

n°1576965
SkippyleGr​andGourou
Posté le 19-06-2007 à 17:56:04  profilanswer
 

deadalnix a écrit :

Avec une batterie de define tu peux faire un truc tres clair rien qu'en apssant des int franceso a raison.

Les "#define", c'est le Mal. :o

 

Utiliser des int serait envisageable dans la mesure où plusieurs warnings seraient identiques. En l'ocurrence, le même warning n'apparait jamais deux fois, mais il peut y avoir plusieurs warnings différents par fonction. Je viens de compter :

Code :
  1. $ grep -r WARNING * | wc -l
  2. 76

:ouch:

 

Je pensais pas en avoir autant, mais tu vois, les int ça sera vite le bordel... ;)


Message édité par SkippyleGrandGourou le 19-06-2007 à 17:56:47
n°1576967
deadalnix
Posté le 19-06-2007 à 18:00:23  profilanswer
 

pfff les #define c'est le mal que si tu en fait n'imp'.
 
un chtit
 
#define WARNING_JASAISPASQUOI 5
 
puis un warn(WARNING_JASAISPASQUOI) c'est quand meme bien mieux qu'un warn(5) . . .

n°1576971
SkippyleGr​andGourou
Posté le 19-06-2007 à 18:19:46  profilanswer
 

Autant utiliser un static const alors, non ?

 

Mais bon, c'est pas le problème, je veux pas définir 80 variables juste pour ça. C'est aussi moche que mon "cout<<WARNING_JASAISPASQUOI<<endl;" (devrais p'têt mettre un cerr d'ailleurs), donc ça ne présente pas grand intérêt.

 

Ce sera un équivalent de this ou rien. Donc rien. :o

 

(À moins que je ne change brusquement d'avis, genre en pleine nuit après un vilain cauchemard où je me ferais agresser par des define en colère...)


Message édité par SkippyleGrandGourou le 19-06-2007 à 18:21:19
n°1577058
deadalnix
Posté le 20-06-2007 à 08:18:36  profilanswer
 

static const cree une varaible en memoire, je ne vois pas ce que ca apporte dans ce cas . . .
 
et puis le cout tu est censé le faire dans la fonction warn non ? avec un switch/case, ya moyen de faire quelque chose.
 
Globalement, quelque soit le systeme que tu choisis de mettre en place, tu devra te taper les 76 execptions.

mood
Publicité
Posté le 20-06-2007 à 08:18:36  profilanswer
 

n°1577276
SkippyleGr​andGourou
Posté le 20-06-2007 à 13:58:47  profilanswer
 

Ben un static const en global a le même effet qu'un define, non ? (Je sais, les variables globales c'est aussi le Mal...)
 
Sinon, c'est bon, j'ai trouvé ce que je cherche : la macro __func__ retourne le nom de la fonction :

Code :
  1. void foo()
  2. {
  3.      cout<<"Je m'appelle "<<__func__<<endl;
  4. }


donne :

Citation :

Je m'appelle foo


:sol:
 
 
Maintenant pour l'implémentation de la fonction Warn() il va falloir que je réfléchisse encore un peu (dans quelle classe la mettre, sachant qu'il y a de l'héritage derrière, le coup des plusieurs warnings pour une même fonction, etc.), mais c'est une autre histoire.
 
Merci, @plouche. :)


Message édité par SkippyleGrandGourou le 20-06-2007 à 14:02:51
n°1577280
deadalnix
Posté le 20-06-2007 à 14:10:05  profilanswer
 

Bon bah tant mieux si ca marche comme ca. Je connaissait pas __func__
 
Par contre, rien a voir entre uen variable globale et un define. Le define modifie ton code source avant compilation, alors que la variable globale se trimbale en memoire comme n'importe quelle variable.

n°1577307
SkippyleGr​andGourou
Posté le 20-06-2007 à 14:53:27  profilanswer
 

À noter que __func__ est un standard du C99, pour des compilateurs ne le respectant pas ça peut être __FUNCTION__, ou autre chose, ou rien...
 
Pour l'implémentation (je le dis même si ça n'intéresse personne, à des fins d'archivage... :D), je pense que le mieux est de définir Warn() dans la classe mère, ainsi qu'une méthode virtuelle qui définira tous les warnings dans une map, et qui sera redéfinie dans les classes filles pour y ajouter les warnings spécifiques à ces classes filles.
 

deadalnix a écrit :

Par contre, rien a voir entre uen variable globale et un define. Le define modifie ton code source avant compilation, alors que la variable globale se trimbale en memoire comme n'importe quelle variable.

Merci pour la clarification. :jap:
 
Mais au final le comportement du programme est le même, donc quel est l'avantage de l'un par rapport à l'autre ? On entend partout que les deux sont à proscrire...
 
 
 

n°1577311
BenO
Profil: Chercheur
Posté le 20-06-2007 à 15:00:36  profilanswer
 

les macros cai surpuissant :o

n°1577388
deadalnix
Posté le 20-06-2007 à 18:26:14  profilanswer
 

le #define peut avoir des effets pervers :
 
si par exemple, je fais :

Code :
  1. #define carre(x) x*x
  2. //pose un probleme avec :
  3. carre(3+5)
  4. //car une fois precompilé, on obtiens :
  5. 3+5*3+5 //ce qui donne pas le carré de 8 soit 64 mais 23.
  6. //Ou pire :
  7. carre(i++)
  8. //devient
  9. i++*i++ //i est incrementé deux fois
  10. //il aurait fallu faire :
  11. #define carre(x) ((x)*(x))
  12. //Mais ca ne protege pas des truc comme la double incrementation


 
Il faut donc faire attention dans la definition de ses marco a bien mettre des parentheses partout car l'oublis d'un parenthese peut etre fatal. de facon generale, sauf dans des cas tres particulier d'optimisation de code, il ne faut donc pas utiliser les macro dans ce but.
 
Par contre les macros sont tres utile pour le nomage de constantes golabales. Si par exemple tu veux cree des erreur numerotées dans ton programme, il peut etre tres fastidieux de se souvenir de quel numero est associé a quelle erreur. les #define sont la pour aider dans ce cas et doivent etre utilisées.
 
Une variable globale constante, je vois pas bien l'utilité, a part si elle est externe et destinée a etre modifiée plus tard, ou bien si on veux s'en servir comme "signature" dans le code compilé, sans vraiment l'utiliser dans le programme (un chargement de registre avec un valeur en dur est jusqu'a 60 fois plus rapide qu'un chargement depuis la memoire, sans compter une eventuelle rupture de pipeline si le bus memoir eest pas disponible, bref a eviter).
 
Une variable globale (non constante) est a eviter car elle est plus souvent source de bug que de solutions, et il existe presque toujours une autre solution au moins aussi efficace. Au pire, et comme on est en C++, on cree un namespace et on faitr des variable globale au namespace. mais bon, c'est pas classe, et c'est surtout plus de problemes que de solutions.

Message cité 1 fois
Message édité par deadalnix le 20-06-2007 à 18:35:26
n°1577483
IrmatDen
Posté le 21-06-2007 à 00:27:57  profilanswer
 

Y'a les enums aussi qui sont trés bien pour définir un set d'erreurs possibles (pour cet exemple précis, parce que c'est trés bien pour définir n'importe quel set de "valeurs" ).

n°1577484
boulgakov
Posté le 21-06-2007 à 00:36:07  profilanswer
 

deadalnix a écrit :

le #define peut avoir des effets pervers :
 
si par exemple, je fais :

Code :
  1. #define carre(x) x*x


 
 
[:kzimir]
 

deadalnix a écrit :

de facon generale, sauf dans des cas tres particulier d'optimisation de code, il ne faut donc pas utiliser les macro dans ce but.

 
 
Je dirais jamais, mais je peux me tromper.
 

deadalnix a écrit :

Par contre les macros sont tres utile pour le nomage de constantes golabales. Si par exemple tu veux cree des erreur numerotées dans ton programme, il peut etre tres fastidieux de se souvenir de quel numero est associé a quelle erreur. les #define sont la pour aider dans ce cas et doivent etre utilisées.[...]Au pire, et comme on est en C++, on cree un namespace et on faitr des variable globale au namespace. mais bon, c'est pas classe, et c'est surtout plus de problemes que de solutions.

 
 
Edit : d'accord aussi avec les enums de IrmatDen, même mieux que mon bidule là-dessous.
 

Code :
  1. struct CodeErreur
  2. {
  3. static const int ERREUR_TRUC;
  4. static const int ERREUR_BIDULE;
  5. static const int ERREUR_MACHIN;
  6. };


 

Code :
  1. #include "CodeErreur.h"
  2. const int CodeErreur::ERREUR_TRUC = 1;
  3. const int CodeErreur::ERREUR_BIDULE = 2;
  4. const int CodeErreur::ERREUR_MACHIN = 3;


 

Code :
  1. ...
  2. if (erreur) {
  3.   warning( CodeErreur::ERREUR_TRUC );
  4. }
  5. ...


Message édité par boulgakov le 21-06-2007 à 00:38:36

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [Résolu] Appeler une fonction avec comme paramètre la fonction d'appel

 

Sujets relatifs
fonction java pour le debit reseau[Résolu][AJAX] server erreur 500
[RESOLU]-[PHP] - Affichage de caractérfe bizard lors d'un includeParamètre dans un tableau
[Eclipse RCP] org.eclipse.core.resources introuvable! Comment faire ?[RESOLU] Récupérer la valeur d'un menu déroulant
Eclipse RCP - Paramètre pour instanciation d'une Vuefonction à corriger
Sélectionner des entrées en fonction de la première lettre d'un champ[résolu] Pourquoi flock ne demande pas un FILE* ?
Plus de sujets relatifs à : [Résolu] Appeler une fonction avec comme paramètre la fonction d'appel


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR