methode binden



  • ou scheisse habs übersehen. thread kann gelöscht werden. erstellen den in c++



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum C++ (auch C++0x) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • das geht doch glaube ich nicht.
    ich bin mir nicht sicher, mir ging vorn paar tagen etwa das gleiche durch den kopf ob man delegates ohne objekte spichern kann (ist das so richtig ausgedrückt?!?)

    normalerweise müsste die funktions pointer deklaration nämlich noch die klasse beinhalten

    // also nicht nur:
    void (*func)(int);
    
    // sondern:
    void (*Klasse1::method)(int);
    

    bin mir aber weder bei der syntax noch bei der richtigkeit meiner antwort sicher



  • Mit std::tr1::function kannst du alles Aufrufbare speichern, also Funktionszeiger, Memberfunktionszeiger und Funktionsobjekte. Mit std::tr1::bind() kannst du sehr kompakt neue Funktionen zusammensetzen.

    Das sind sehr mächtige Werkzeuge, die leider viele C++-Programmierer nicht kennen und deshalb oft umständlichere Lösungen über Laufzeitpolymorphie entwickeln.



  • habs jetzt erstmal so gelöst.

    #include <boost/bind.hpp>
    #include <boost/function.hpp>
    
    #include <iostream>
    
    class A {
      public:
      boost::function<void (int)> doit2;
    };
    
    class B{
      public:
      void das_hier(int x) {
        std::cout << x << std::endl;
      }
      A a;
      void doit(int _x) {
        a.doit2(_x);
      }
      void connect() {
        a.doit2 = boost::bind(boost::mem_fn(&B::das_hier), this, _1);
      }
    };
    
    int main() {
      B b;
      b.connect();
      b.doit(1234);
    
      return 0;
    }
    

    bekomme es aber nicht hin, dass eine methode der Klasse A die bindung erledigt. ich möchtedie bindung, die in B::connect geschieht, durch Klasse A erzeugen. kennt da jemand ne möglichkeit?

    @Nexus
    ich verwende boost bibliotheken. die haben sehr ähnliche klassen, die aber, soweit ich weiss, etwas mächtiger sind, weil sie nicht auf anzahl parameter beschränken.



  • habs glaube ich hinbekommen... 😃
    stand wohl n bisschen aufm schlauch 🙄
    falls jemand verbesserungen kennt immer her damit. ansonnsten danke an alle die geholfen haben 👍

    #include <boost/bind.hpp>
    #include <boost/function.hpp>
    
    #include <iostream>
    
    class A {
      public:
      boost::function<void (int)> doit;
      void binde(boost::function<void (int)> _func) {
        doit = _func;
      };
    };
    
    class B{
      A a;
      void das_hier(int x) {
        std::cout << x << std::endl;
      }
    
      public:
      void doit(int _x) {
        a.doit(_x);
      }
    
      void connect() {
        a.binde(boost::bind(&B::das_hier, this, _1));
      }
    };
    
    int main() {
      B b;
      b.connect();
      b.doit(134234);
    
      return 0;
    }
    


  • Kannst Du mal erklären, was Du genau erreichen willst? Also nicht, wie Du es machen willst, sondern was Du machen willst?



  • pi88el schrieb:

    falls jemand verbesserungen kennt immer her damit. ansonnsten danke an alle die geholfen haben 👍

    int main() {
      B b;
      b.das_hier(134234);
    
      return 0;
    }
    

    Tut genau das Gleiche, auf das gleiche Objekt. Nur ohne Bindung. Was soll die Indirektion hier bringen?



  • Tachyon schrieb:

    Kannst Du mal erklären, was Du genau erreichen willst? Also nicht, wie Du es machen willst, sondern was Du machen willst?

    klasse A ist eine relativ große klasse die selbständig in einem eigenen thread bestimmte dinge ausführt. klasse B steht für einige verschiedene klassen die klasse A verwenden. wenn irgendwelche events in klasse A passieren sollen bestimmte methoden der jeweiligen klasse B oder zum teil auch normale funktionen ausgeführt werden. deswegen binde ich bestimmte methoden an diese events. threadsicherheit muss dadurch vollständig in klasse B gewährleistet sein. hätte auch vererbung einsetzten können, was aber bei ("globalen") funktionen wieder verkompliziert wird.
    so wie ich es jetzt gemacht habe, kann ich sowohl funktionen als auch methoden binden.

    soviel zum hintergrund. wie gesagt wenn jemand ne bessere lösung hat her mit... kann mich aber nicht zu lange aufhalten damit... sollte diese woche vertig werden.

    Tachyon schrieb:

    Tut genau das Gleiche, auf das gleiche Objekt. Nur ohne Bindung. Was soll die Indirektion hier bringen?

    hier nichts. ist nur ein kleines beispiel. das richtige projekt ist etwas größer. und zuviel quelltext zu posten führt meistens dazu das sich den niemand durchliest weil es zu anstrengend ist sich in code von paar hundert zeilen einzuarbeiten.



  • Irgendwie so?

    class Service //Deine Klasse A
    {
    public:
        typedef boost::function<void (int)> ServiceCallback;
    
        void registerCallback(ServiceCallback const & callback)
        {
            this->callback = callback;
        }
    private:
        void serviceRoutine()
        {
            //laeuft in einem Thread...
            for(;;)
            {
                //...
                if(!callback.emtpy() && event)
                {
                    callback(foo);
                }            
            }
        }
    
        ServiceCallback callback;
    };
    
    class B
    {
    public:
        void handleEvent(int a)
        {
            //was auch immer
        }
    };
    
    int main()
    {
        Service service;
        B item;
    
        service.registerCallback(boost::bind(&B::handleEvent, &item, _1));    
    }
    

    So ist es flexibler, weil so der Service nichts mehr von seinen Clients wissen muss. Wenn es unterschiedliche Events gibt, welche unterschiedliche Funktionen auslösen sollen, dann packe z.B. mehrere Funktoren in eine std::map und löse die passende Funktion aus.



  • ja genau so habe ich es gemeint. und genauso mach ich es ja auch. nur das ich die bindung inerhalb der klasse B mache. sonnst sehe ich da kein unterschied.


Anmelden zum Antworten