IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[D�butant] Fonction membre et handler


Sujet :

C++

  1. #1
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2003
    Messages
    67
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 67
    Par d�faut [D�butant] Fonction membre et handler
    Bonsoir,
    Je m'exprimerais mieux en vous donnant le code qu'en formulant des phrases en Fran�ais, donc voici le code :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    std::string chaine_calculee = ....;
    void appele_fonction(void (*fonction)(string))
           {
              fonction(chaine_calculee);
           }
    class Test {
          ....
          void traite_les_infos (std::string les_infos) 
          {
              Affiche les informations
          }
          void fonction_beta() {
              appele_fonction( traite_les_infos);
         }
    };
    
    Test t();
    t.fonction_beta();
    Seulement l� il me sort une erreur car il attend une fonction et non une m�thode membre d'une classe. Comment contourner ce probl�me au niveau de la classe ?

    Je vous remercie.

  2. #2
    R�dacteur/Mod�rateur
    Avatar de JolyLoic
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2004
    Messages
    5 463
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 51
    Localisation : France, Yvelines (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Ao�t 2004
    Messages : 5 463
    Par d�faut
    Pour acc�der � la fonction globale qui est cach�e par une fonction membre de ta classe, tu peux indiquer son "chemin d'acc�s" depuis le namespace global. Ici, �a veut dire ::appele_fonction mais si elle �tait dans le namespace toto, tu aurais pu �crire toto::appele_fonction ou ::toto::appele_fonction.
    Ma session aux Microsoft TechDays 2013 : D�velopper en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage � la d�couverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'h�sitez pas � me contacter.

  3. #3
    R�dacteur
    Avatar de Laurent Gomila
    Profil pro
    D�veloppeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    D�tails du profil
    Informations personnelles :
    �ge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activit� : D�veloppeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par d�faut
    Le type de ta fonction membre est void (Test::*fonction)(string), c'est incompatible avec le param�tre que tu attends.

    Tu peux utiliser boost.function et boost.bind pour faire quelque chose de g�n�rique, ou encore les �quivalents dans la biblioth�que standard si tu ne veux pas de boost.

  4. #4
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2003
    Messages
    67
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 67
    Par d�faut
    Je vous remercie pour vos r�ponses.
    Est ce que ceci serait une bonne solution ?
    util.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void appele_fonction_n(int n, void (*fonction)(string))
    {
       string chaine_calculee;
       for(int i=0; i<n; i++)
       {
          chaine_calculee = "calcul_en_fonction_de_n";
          fonction(chaine_calculee);
       }
    }
    Test.h
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Test {
    private:
          int n_call;
          string results*;
    public:
          Test();
          void fonction_beta();
          friend void traite_les_infos (string les_infos);
    };
    Test.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    #include "Test.h"
    #include "util.h"
    Test* global;
    Test::Test(int c)
    {
       n_call = c;
       results = new string[n_call];
       global = this;
    }
    void traite_les_infos (string les_infos)
    {
         static int cpt=0;
         global->results[cpt++] = les_infos;
    }
    void Test::fonction_beta() 
    {
         appele_fonction_n(n_call, traite_les_infos);
    }
    main.cpp
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #include "Test.h'
    int main()
    {
         Test t();
         t.fonction_beta();
         return 0;
    }

  5. #5
    Expert confirm�
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    D�cembre 2003
    Messages
    3 549
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : D�cembre 2003
    Messages : 3 549
    Par d�faut
    string results*;
    J'imagine que tu voulais �crire string *results; ?

    C'est mauvais, et ceci pour plusieurs raisons.
    - Ton pointeur global qui n'est initialis� qu'� la construction d'un Test c'est inutile et dangereux. Ce n'est rien de plus qu'un hack.
    - T'as une fuite m�moire
    - T'utilises pas les initaliseurs des constructeurs
    - T'arr�tes pas de faire des copies de cha�ne pour rien
    - Deux types de bonnes solutions t'ont �t� donn�es (fixer le type pour une fonction membre d'une classe particuli�re ou utiliser des foncteurs polymorphiques) et tu n'en as appliqu� aucune. Il y en a aussi une troisi�me qui est bonne et qui utilise des templates, ce qui te permet d'avoir encore plus de flexibilit� que les foncteurs polymorphiques tout en ayant de meilleures performances mais ne permet pas un type unique et a d'autres d�savantages propres � l'utilisation de templates.

  6. #6
    Membre confirm�
    Profil pro
    Inscrit en
    Ao�t 2003
    Messages
    67
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 67
    Par d�faut
    Je te remercie pour ta r�ponse.

    En fait, sur le terrain j'ai mofifi� le type de pointeur sur fonction qu'attend en entr�e ma m�thode appele_fonction_n, en m'inspirant de la remarque Laurent Gomila (2 �me post).

    Seulement je me demandais que faire dans le cas suivant :
    Supposons que ma fonction appel_fonction_n appartienne � une librairie qui serait appel�e par des programmes autres que les miens, et peut �tre m�me des programmes C. La solution des espaces de nom est donc non g�n�rique.
    Ta solution de template est tout aussi int�ressante mais ma fonction ne pourra �tre invoqu�e que par du code C++.
    Pour mieux comprendre mon "souci", suppose que la fonction en question soit une fonction C, par exemple la fonction de gestion de signaux "signal" � laquelle il faut passer un handler qui sera appel� � chaque r�ception d'un certain signal. Mon but serait donc par exemple de passer dans "signal" une m�thode de classe.
    Puis je eviter de passer par boost ? D'ailleurs que fait boost quand j'app�le bind ou function ?
    Suis-je contraint de hacker dans ce cas l� car je mixe du C et du C++ ?

    Merci.

  7. #7
    Expert confirm�
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    D�cembre 2003
    Messages
    3 549
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : D�cembre 2003
    Messages : 3 549
    Par d�faut
    Supposons que ma fonction appel_fonction_n appartienne � une librairie qui serait appel�e par des programmes autres que les miens, et peut �tre m�me des programmes C. La solution des espaces de nom est donc non g�n�rique.
    C'est pour �a qu'il y a les deux autres possibilit�s.

    Ta solution de template est tout aussi int�ressante mais ma fonction ne pourra �tre invoqu�e que par du code C++.
    Pouvoir �tre invoqu�e par du code C est un tout autre probl�me. Le meilleur moyen est probablement de faire une fonction � part qui enrobe la fonction principale pour le cas sp�cial du C.

    De toutes mani�res, si tu veux faire une interface C, il faut que tous les param�tres soient en C.
    �a impose des limitations �videntes.

    Soit tu fais une interface C, qui sera mauvaise du point de vue du C++, soit tu fais une interface C++, inutilisable en C.

    Dans le cas de l'interface C, g�n�ralement on permet un argument additionnel de type void* pour permettre � la fonction de conserver des informations (comme ici, ton instance de Test).

    En fait, sur le terrain j'ai mofifi� le type de pointeur sur fonction qu'attend en entr�e ma m�thode appele_fonction_n, en m'inspirant de la remarque Laurent Gomila (2 �me post).
    Je me demande si tu as vraiment bien fait cela.
    Il te faut aussi un objet en plus de ce pointeur de fonction.

    Puis je eviter de passer par boost ?
    Si tu veux r�ecrire de mani�re moins g�n�riques les composants de boost, libre � toi.

    D'ailleurs que fait boost quand j'app�le bind ou function ?
    Ces composants ne sont pas uniquement dans boost mais aussi dans TR1 et dans le prochain standard C++.
    bind est un outil assez puissant pour cr�er facilement des foncteurs � partir d'autres foncteurs ou fonctions, en fournissant par exemples objets ou param�tres.
    function est un foncteur polymorphique, qui peut donc contenir n'importe quel type de foncteur du moment qu'il r�pond � une signature donn�e. Cela emp�che du coup la surcharge et la g�n�ricit� du foncteur.

Discussions similaires

  1. R�ponses: 10
    Dernier message: 03/02/2005, 13h09
  2. R�ponses: 5
    Dernier message: 12/01/2005, 20h58
  3. [D�butant] fonction CALLBACK
    Par tlt dans le forum MFC
    R�ponses: 2
    Dernier message: 29/10/2004, 16h55
  4. [Ada] [D�butant] Fonction et Put_Line
    Par hitchie dans le forum Ada
    R�ponses: 1
    Dernier message: 18/10/2004, 09h44
  5. Thread avec une fonction membre d'une classe
    Par SteelBox dans le forum Windows
    R�ponses: 6
    Dernier message: 01/03/2004, 01h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo