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

Langage C++ Discussion :

Reference d'une fonction membre


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    Septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2007
    Messages : 71
    Par défaut Reference d'une fonction membre
    Vu qu'il est possible de créer des pointeurs vers de fonctions membres et des reference de fonction, je voulais savoir s'il était possible de créer des reference vers des fonctions membres d'une classe.

    Merci

  2. #2
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Bonne question, j'ai jamais essayé mais je pense que ça ne dois pas être possible: un pointeur de fonction ne pointe pas sur une instance mais sur l'adresse en mémoire où se trouve la dite fonction (forçant a fournir une instance de classe dans le cas d'un fonction membre).

    Or une référence n'est (théoriquement) utilisé que pour une instance de type (le fait que la référence soit implémentée comme un pointeur est un détail d'implémentation, on doit prendre la référence comme un surnom d'un objet).

    Donc je dirais que ce n'est pas possible. Maintenant je m'en vais vérifier ce que dis VC9.

    Au passage, si tu utilises std::tr1::function<> au lieu d'adresses de pointeurs "nus" alors tu as un fonctor qui lui est un objet et donc peut avoir une référence.

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Oui, on peut.
    Regarde:

    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
    #include <iostream>
     
    struct A
    {
        void foo(){std::cout<<"foo a"<<std::endl;}
    };
     
    int main(int argc, char const *argv[])
    {
     
        typedef void (A::*ptrAfct)();
        ptrAfct ptr=&A::foo;
        const ptrAfct& ref=&A::foo;
        A a;
        (a.*ref)();
        return 0;
    }
    A noter que la référence doit être const. Au vu de l'erreur sortie par g++, je dirais que c'est car &A::foo doit renvoyer une copie et comme on ne peut lier une référence non const avec un temporaire, boom.

    Sinon +1 pour les tr1::function/boost::function.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    J'ai donc testé sous VC9 et visiblement j'arrive a faire en sorte d'utiliser une référence à une fonction globale.
    Par contre je ne trouve pas la syntaxe pour déclarer le typedef d'une référence à une fonction membre. L'utilisation de & à la place de * ne passe pas.
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #include <iostream>
     
    void test()
    {
    	std::cout << "Global : It works!\n";
    }
     
    class Test
    {
    public:
     
    	void doIt()
    	{
    		std::cout << "Member : It works!\n" ;
    	}
     
     
    };
     
    typedef void (&SimpleFunction)();
    typedef void (Test::*MemberFunction)();
     
     
    int main()
    {
    	SimpleFunction myfunc = test;
    	myfunc();
     
    	Test myTest;
    	MemberFunction myMemberFunc = &Test::doIt;
    	(myTest.*myMemberFunc)();
     
    	std::cin.ignore();
    	return 0;
    }
    Ce code marche, comme dit je n'ai pas trouvé de moyen d'avoir une référence à une fonction membre.

    Peut être que quelqu'un plus au fait du standard pourrait donner des précisions là dessus? Ca m'étonne déjà que la référence a la fonction globale marche.

  5. #5
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    boost::function avec boost::bind te permet cela assez facilement

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    #include <iostream>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
     
    class A
    {
    	typedef boost::function< void() > callback_t;
    public:
    	void Foo() const
    	{
    		myCallback();
    	}
     
    	void BindFunc( const callback_t& cb )
    	{
    		myCallback = cb;
    	}
     
    	callback_t myCallback;
    };
     
    void foo()
    {
    	std::cout << "hello from global" << std::endl;
    }
     
    class B
    {
    public:
    	void Foo()
    	{
    		std::cout << "hello from B" << std::endl;
    	}
    };
     
    int main()
    {
    	A a;
    	a.BindFunc( foo );
    	a.Foo();
     
    	B b;
    	a.BindFunc( boost::bind( &B::Foo, &b ) );
    	a.Foo();
    	return 0;
    }

  6. #6
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Par contre, est-ce que c'était prévu par le standard? (et est-ce que ça marche sur les autres compilo?)

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    Septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2007
    Messages : 71
    Par défaut
    Citation Envoyé par Klaim Voir le message
    J'ai donc testé sous VC9 et visiblement j'arrive a faire en sorte d'utiliser une référence à une fonction globale.
    Par contre je ne trouve pas la syntaxe pour déclarer le typedef d'une référence à une fonction membre. L'utilisation de & à la place de * ne passe pas.
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #include <iostream>
     
    void test()
    {
    	std::cout << "Global : It works!\n";
    }
     
    class Test
    {
    public:
     
    	void doIt()
    	{
    		std::cout << "Member : It works!\n" ;
    	}
     
     
    };
     
    typedef void (&SimpleFunction)();
    typedef void (Test::*MemberFunction)();
     
     
    int main()
    {
    	SimpleFunction myfunc = test;
    	myfunc();
     
    	Test myTest;
    	MemberFunction myMemberFunc = &Test::doIt;
    	(myTest.*myMemberFunc)();
     
    	std::cin.ignore();
    	return 0;
    }
    Ce code marche, comme dit je n'ai pas trouvé de moyen d'avoir une référence à une fonction membre.

    Peut être que quelqu'un plus au fait du standard pourrait donner des précisions là dessus? Ca m'étonne déjà que la référence a la fonction globale marche.
    En fait, j'ai la même chose avec gcc, d'ou ma question.
    Pour être plus précis, mon but est de créer une classe template qui prend une fonction membre en paramètre template, le truc étant qu'en utilisant un pointeur cela ne marche pas.
    Aussi je me demandais si cela ne venait pas de l'opérateur & utilisé dans ma déclaration pour obtenir l'adresse de ma fonction, d'ou l'idée d'utiliser une reference de fonction membre à la place.
    Mais quand j'essaie de faire cela, comme dit plus haut: l'utilisation de & à la place de * ne passe pas car gcc me sort une erreur de syntaxe.

    Ps: Davidbrcz > J'ai l'impression que ce que tu fais, c'est prendre une reference vers un pointeur de fonction, non?

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par bountykiler Voir le message
    Ps: Davidbrcz > J'ai l'impression que ce que tu fais, c'est prendre une reference vers un pointeur de fonction, non?
    J'ai la même impression...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Réponses: 14
    Dernier message: 16/05/2006, 11h26
  2. Réponses: 3
    Dernier message: 29/04/2006, 13h02
  3. Réponses: 4
    Dernier message: 01/12/2005, 12h33
  4. Réponses: 3
    Dernier message: 28/11/2005, 12h15
  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