39 votes

Pointeur de fonction C++ (membre de classe) vers une fonction membre non statique

class Foo {
public:
    Foo() { do_something = &Foo::func_x; }

    int (Foo::*do_something)(int);   // pointeur de fonction vers une fonction membre de classe

    void setFunc(bool e) { do_something = e ? &Foo::func_x : &Foo::func_y; }

private:
    int func_x(int m) { return m *= 5; }
    int func_y(int n) { return n *= 6; }
};

int
main()
{
    Foo f;
    f.setFunc(false);
    return (f.*do_something)(5);  // <- Non ok. Erreur de compilation.
}

Comment puis-je faire fonctionner cela?

36voto

Nick Dandoulakis Points 26809
class A{
    public:
        typedef int (A::*method)();

        method p;
        A(){
            p = &A::foo;
            (this->*p)(); // <- astuce 1, appel interne
        }

        int foo(){
            printf("foo\n");
            return 0;
        }
    };

    void main()
    {
        A a;
        (a.*a.p)(); // <- astuce 2, appel externe
    }

33voto

James Curran Points 55356

La ligne que vous voulez est

   return (f.*f.do_something)(5);

(Cela compile - je l'ai essayé)

"*f.do_something" se réfère au pointeur lui-même --- "f" nous indique où obtenir la valeur do_something de. Mais nous devons quand même fournir un objet qui sera le pointeur this lorsque nous appellerons la fonction. C'est pourquoi nous avons besoin du préfixe "f.".

3voto

Volkan Ozyilmaz Points 81
class A {
    int var;
    int var2;
public:
    void setVar(int v);
    int getVar();
    void setVar2(int v);
    int getVar2();
    typedef int (A::*_fVar)();
    _fVar fvar;
    void setFvar(_fVar afvar) { fvar = afvar; }
    void insideCall() { (this->*fvar)(); }
};

void A::setVar(int v)
{
    var = v;
}

int A::getVar()
{
    std::cout << "A::getVar() is called. var = " << var << std::endl;
    return var;
}

void A::setVar2(int v2)
{
    var2 = v2;
}

int A::getVar2()
{
    std::cout << "A::getVar2() is called. var2 = " << var2 << std::endl;
    return var2;
}

int main()
{
    A a;
    a.setVar(3);
    a.setVar2(5);

//    a.fvar = &A::getVar;
    a.setFvar(&A::getVar);
    (a.*a.fvar)();

    a.setFvar(&A::getVar2);
    (a.*a.fvar)();

    a.setFvar(&A::getVar);
    a.insideCall();

    a.setFvar(&A::getVar2);
    a.insideCall();

    return 0;
}

J'ai étendu la réponse de Nick Dandoulakis. Merci.

J'ai ajouté une fonction qui définit le pointeur de fonction membre depuis l'extérieur de la classe. J'ai ajouté une autre fonction qui peut être appelée depuis l'extérieur pour montrer l'appel interne du pointeur de fonction membre.

0voto

Suvesh Pratapa Points 3735

Essayez (f.*faire_ quelque_chose)(5);

-4voto

Je pense qu'appeler un membre non statique de la classe pourrait également être fait en utilisant une fonction membre statique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X