Methoden Pointer als Parameter übergeben



  • Hi,

    ich versuche eine Methode von einer Klasse als Pointer zu übergeben, leider erhalte ich folgenden Fehler:

    error: no matching function for call to ‘A::addView(int, void (B::*)(void*))’
    note: candidates are: void A::addView(int, void (*)(void*))
    

    Natürlich kennt er B:: nicht aber wie kann ich das lösen? Leider kann ich die addView Methode nicht ändern, da es von einer externen Bibliothek ist.
    Inmoment löse ich es so, dass ich die Methode "draw" statisch mache, was aber unschön ist, da dann die Member Variablen der Klasse B statisch sein müssen. 😞

    Hier der minimale Testcode:

    class A {
    public:
        void addView(int v,void (*call)(void*));
    };
    
    class B {
    public:
        void draw(void*);
    
        inline void test() {
           A a;
           a.addView(0, &B::draw);
        }
    };
    

    Mfg
    frye





  • ok soweit ich das verstanden habe muss aber die addView Methode dann auch geändert werden, was ich aber nicht kann.

    Da addView eigentlich eine C-FunKtion ist, welches einen Zeiger auf eine
    Funktion als parameter wünscht. Allerdings möchte ich gerne einen Zeiger auf
    eine Member-Methode meiner Klasse geben.

    Nach dem Artikel habe ich es jetzt so umgeschrieben:

    class B {
    public:
        void draw(void*);
    
        inline void test() {
           A a;
           typedef void (B::fct_t*)(void*);
           fct_t f = &B::draw
           a.addView(0, f);
        }
    };
    

    Fehlermeldung ist aber immernoch die selbe...
    Also eigentlich geht es mir das die draw Methode die Member Variablen von B zugreifen kann ohne, dass sie statisch sein müssen oder public sind.
    Vielleicht kann man das auch noch anders lösen?

    Mfg
    frye



  • Zeiger auf freie Funktionen und auf Memberfunktionen sind zueinander inkompatibel. Diese Limitierung ist mühsam, darum existiert in modernerem C++ auch die Abstraktion std::tr1::function . In C++0x gibts zudem Lambda-Ausdrücke.

    Da du an das bestehende Interface gebunden bist, musst du eine dir auch eine freie Funktion basteln. Immerhin gibts einen void* -Parameter, möglicherweise kannst du ihn für deine Argumente (z.B. den this -Pointer) einsetzen.



  • ok danke für die Aufklärung.
    Dann habe ich es jetzt anders gelöst, indem ich eine dummy C-Funktion normal registriere und in der C-Funktion eine Methode der Klasse B aufrufe, die wiederum normal auf alle Member Variablen Zugriff hat.
    Leider muss die Klasse B in der cpp als globale Variable deklariert sein und die draw Methode public aber das kann ich verkraften. 😉

    Mfg
    frye



  • Das heisst, du kannst den void* nicht für deine Zwecke einsetzen? Wird er für den Callback benutzt?


Anmelden zum Antworten