Function-Pointer , und Class Method



  • @Schlangenmensch ja sorry ich wollte auch die "ProgressCallFunc" Menber funktion zuweisen. und ich habe leider deinen Vorschlag nich verstanden­čśů

    @theta : Ja tut mir leid, hab das falsche Unterforum gew├Ąhlt. Ok dachte funktionptr und member -funktionptr machen keinen unterschied . d.h. mit dem std::function kann ich sowas ├╝bergreifen machen? Kannst du mir das anhand meines Beispiels mit dem std:Function zeigen?



  • @SoIntMan sagte in Function-Pointer , und Class Method:

    d.h. mit dem std::function kann ich sowas ├╝bergreifen machen?

    Nein, nat├╝rlich nicht. Das habe ich nur geschrieben, um dich zu verwirren.

    Aber ernsthaft: Ja, das kannst du. Und dir wird ein weiteres "Problem" auffallen. Denn eine nicht-statische Memberfunktion muss auf einem Objekt aufgerufen werden - im Beispiel von dir gibt es beim Aufruf aber kein Objekt, auf dem die Memberfunktion aufgerufen werden kann. Aber auch das kann man mit std::function<..> einfach l├Âsen. Schau dir auch mal std::bind(..) an. Und probier auch die Idee von Schlangenmensch mit den Lambdas aus.



  • @SoIntMan sagte in Function-Pointer , und Class Method:

    Ok dachte funktionptr und member -funktionptr machen keinen unterschied

    Naja, stell dir doch mal vor, dass du bei Memberfunktionen irgendwie noch ├╝bertragen musst, um welches konkrete Objekt deiner Klasse es sich handelt. In anderen Sprachen, wie z.B. Python, musst du bei Memberfunktionen self (entspricht this in C++) explizit als ersten Parameter angeben. In C++ passiert das implizit, ist aber im Prinzip der Grund, warum Funktion und Member-Funktion unterschiedlich sind.

    Edit: weiterer Lesevorschlag ist std::mem_fn



  • Ein Member-Funktionszeiger ben├Âtigt immer ein Objekt (Instanz) als zus├Ątzliches Argument, f├╝r das es aufgerufen wird. Wenn du die Klassenfunktion statisch (static) machst, dann kannst du sie mit einem normalen Funktionszeiger aufrufen (&Foo::ProgressCallFunc), kannst jedoch innerhalb dieser Funktion nicht auf nicht-statische Member zugreifen.

    Wenn es eine reine C++-L├Âsung werden soll, dann nimm, wie erw├Ąhnt, std::function (s. Beispiel) oder eben als Template.

    Wenn es auch von C aus aufrufbar sein soll, dann ├╝bergebe als zus├Ątzlichen Parameter void *, welches du dann innerhalb der Funktion wieder in einen Klassenzeiger zur├╝ck casten mu├čt.



  • @SoIntMan sagte in Function-Pointer , und Class Method:

    @Schlangenmensch ja sorry ich wollte auch die "ProgressCallFunc" Menber funktion zuweisen. und ich habe leider deinen Vorschlag nich verstanden­čśů

    Vielleicht hilft das weiter:
    https://stackoverflow.com/questions/6458612/c0x-proper-way-to-receive-a-lambda-as-parameter-by-reference

    Der Aufruf von dem Template k├Ânnte z.B. dann so aussehen (ungetestet):

    void DoFoo()
    {
       auto callBack = [this](int i)
          {
             ProgressCallFunc(i);
          };
       DoBar(callBack);
    }
    


  • Kleiner Hinweis noch, ich verwende (muss) VS 2008 C++ ­čÖé



  • @SoIntMan sagte in Function-Pointer , und Class Method:

    Kleiner Hinweis noch, ich verwende (muss) VS 2008 C++ ­čÖé

    Das ist ja erst 11 Jahre alt. Seitdem hat sich auch in der IT fast gar nichts ver├Ąndert. Nur 3 neue C++-Standards. Sorry, aber wenn du nicht einmal C++11 nutzen kannst, dann ist irgendwas falsch.

    Ohne Lambdas? Dann mach dir ne eigene struct, speichere das this des Foo-Objektes darin und ├╝berlade operator(). Oder besser: beseitige den Grund, warum du noch VS 2008 nutzen musst.



  • @wob: so ist das nunmal , kann es nicht ├Ąndern.. ­čś×

    Naja ich bekomme das nicht hin , auch mit dem std::function und std:bind nich... ich denke ich lasse das einfach



  • @SoIntMan std::function ist auch erst ab C++11 verf├╝gbar.

    Du kannst dir eine Hilfsklasse mit operator() erstellen:

    class Bar {
    public:
        template <typename Fn>
        static void DoBar(Fn f) {
            for (int i = 0; i < 100; ++i) {
                // Do hard work
                f(i);
            }
        }
    };
    
    class Foo {
    private:
        void ProgressCallFunc(int i);
    
    public:
        void DoFoo();
        friend class FooLambda;
    };
    
    class FooLambda {
        Foo *foo;
    
    public:
        explicit FooLambda(Foo *foo) : foo(foo) {}
        void operator()(int i) { foo->ProgressCallFunc(i); }
    };
    
    void Foo::ProgressCallFunc(int i) {
        //Get Progress state
    }
    
    void Foo::DoFoo() {
        // Call (in Thread)
        Bar::DoBar(FooLambda(this));
    }
    

    Das FooLambda k├Ânnte man durch ein Lambda ersetzen - seit 2011. Du musst eben irgendwie daf├╝r sorgen, dass das ProgressCallFunc wei├č, auf welches this es angewendet werden soll.



  • Hier noch ein kleines old-school Beispiel mit Pointer to Member Function:

    #include <iostream>
    
    class Foo;
    typedef void(Foo::*ProgressCallbackFunc)(int i);
    
    class Bar
    {
    public:
        static void DoBar(ProgressCallbackFunc funcptr, Foo& foo)
        {
            for (int i = 0; i <= 10; ++i)
            {
                (foo.*funcptr)(i*10);
            }
        }
    };
    
    class Foo
    {
    private:
        void ProgressCallFunc(int i)
        {
            std::cout << "Progress: " << i << "%\n";
        }
    
    public:
        void DoFoo()
        {
            Bar::DoBar(&Foo::ProgressCallFunc, *this);
        }
    };
    
    int main()
    {
        Foo foo;
        foo.DoFoo();
    }
    


  • Mahlzeit:

    @wob : Danke f├╝r dein Beispiel:) Aber f├╝r meinen Nutzen wird das zu Komplex­čśů

    @theta : Auch sch├Ânes Beispiel, aber ging das auch generisch?, so dass Foo irgend eine Klassen sein kann?



  • @SoIntMan sagte in Function-Pointer , und Class Method:

    aber ging das auch generisch?

    So?

    template  <typename MemFn, typename Instance>
    static void DoBar(MemFn funcptr, Instance& foo)
    


  • @SoIntMan, es gibt ├Ąquivalente Funktionalit├Ąt in Boost (boost::function<..> und boost::bind(..)). Falls du das benutzen kannst, w├Ąre das sicher ein Vorteil.


Log in to reply