Merkwürdiger Methodenaufruf - Parameter



  • Hallo,

    stöbere mich gerade durch einige c++ beispiele durch und dabei ist mir folgendes konstrukt aufgefallen, welches ich nicht verstehe:

    void funcA(void (*intHandler) (int));
    

    Was wird hier als Parameter genau erwartet??? Es sollte irgendwie eine Referenz auf eine Funktion übergeben werden. Ich verstehs einfach nicht. Vielleicht kann mir einer von Euch dies erklären?

    Danke für Eure Unterstützung.



  • du musst einen Pointer auf eine Funktion übergeben, die als Parameter einen int erwartet und nichts zurückgibt.

    void foo(int x)
    {
        std::cout << x;
    }
    
    int main()
    {
        funcA(&foo);
    }
    


  • Hallo und danke für deine Antwort.

    Ich habe versucht das Ganze mal in ein eigenes Programm zu bringen, bekomme aber einen Fehler beim compilieren.

    ClassA.h

    class ClassA
    {
    private:
    
    public:
    	ClassA();
    	~ClassA();
    	void funcA();
    protected:
    
    };
    

    ClassA.cpp

    #include "ClassA.h"
    #include "ClassB.h"
    
    ClassA::ClassA()
    {
    }
    
    ClassA::~ClassA()
    {
    }
    
    void ClassA::funcA()
    {
    	ClassB b = ClassB::getInstance();
    	b.funcB(&funcA);
    }
    

    ClassB.h

    class ClassB
    {
    private:
    
    public:
    	ClassB();
    	~ClassB();
    	void init();
    	void funcB(void (*intHandler)(int));
    	static ClassB& getInstance()
    	{
    		return *pClassB;
    	}
    protected:
    	static ClassB* pClassB;
    };
    

    ClassB.cpp

    #include "ClassB.h"
    #include <iostream>
    
    using namespace std;
    
    ClassB* ClassB::pClassB = 0;
    
    ClassB::ClassB()
    {
    }
    
    ClassB::~ClassB()
    {
    }
    
    void ClassB::init()
    {
    	ClassB::pClassB = new ClassB();
    }
    
    void ClassB::funcB(void (*intHandler)(int))
    {
    	cout << "\n" << &intHandler << endl;
    }
    

    Compiler Ausgabe:

    classa.cpp(15) : error C2276: '&' : illegal operation on bound member function expression
    

    Wo liegt hier der Fehler???



  • hat sich erledigt.

    lösung:

    ClassA.cpp

    #include "ClassA.h"
    #include "ClassB.h"
    
    ClassA::ClassA()
    {
    }
    
    ClassA::~ClassA()
    {
    }
    
    void funcC(int i)
    {
    }
    
    void ClassA::funcA()
    {
    	ClassB b = ClassB::getInstance();
    	b.funcB(&funcC);
    }
    

    Anscheinend können hier Pointer auf andere Methoden nicht übergeben werden oder evt. mit irgendeinem cast?.



  • Du hattest oben versucht, eine memberfunktion von ClassA zu übergeben. das geht so nicht. Die hat eine andere Signatur wie eine freie Funktion mit der gleiche Parameterliste, da ja noch this mit übergeben werden muß. Siehe auch mal in der FAQ
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39450.html



  • danke für deine antwort. ich habe jetzt versucht das in mein beispiel einzubauen aber irgendwie wird das nichts.

    könntest du mir evt. einen tip geben?



  • Ich bin noch immer am Versuchen, aber leider habe ich noch immer keine Lösung gefunden. Vielleicht weiß ja einer von Euch noch einen Weg???



  • Du kannst nur statische Methoden und globale Funktionen per Funktionszeiger übergeben, darum benötigst du eine andere Möglichkeit, an eine Klasseninstanz zu kommen, z.B.:

    class ClassA
    {
      static KlasseA classInst;
    public:
      static void myFunc(int i)
      {
        classInst.methodeA(i);
      }
    
      void methodeA(int i)
      {...}
    };
    
    ...
    ClassB b
    b.funcb(&ClassA::myFunc);
    

    (aus dem Grund hantieren Thread-Bibliotheken und ähnliches oft mit einem void-Zeiger, dem du ein Zielobjekt übergeben kannst)



  • jopperl schrieb:

    Ich bin noch immer am Versuchen, aber leider habe ich noch immer keine Lösung gefunden. Vielleicht weiß ja einer von Euch noch einen Weg???

    Falls du noch immer hier eine nicht-statische Membermethode übergeben willst: Das lässt die verlangte Signatur einfach nicht zu. Ein Zeiger auf eine Methode braucht immer auch noch einen Instanzzeiger, die Signatur lässt aber keine Übergabe selbigen zu. Sofern du nicht die Funktion mit dem Callbackparameter selbst in Zugriff hast, lässt sich da auch nichts dran ändern.

    cu André



  • in dem oben geposteten Link gibts doch genau so ein Beispiel. ABer usm dir nochmal klarer zu gestalten:

    void (*afunptr)(int); //afunptr ist ein Pointer auf eine Funktion, die einen int als Parameter hat und keinen Rückgabewert
    
    std::string (MyClass::*amemfunptr)(); //amemfunptr ist ein Pointer auf eine Memberfunktion von MyClass, die keine Parameter nimmt und einen std::string liefert
    

    Alternativ kann mans auch per typedefs machen:

    typedef void (*FunPtr)(int); //FunPtr ist jetzt ein Alias für den Typ "Pointer auf FUnktion mit Parameter int ohne Rückgabewert"
    
    FunPtr afunptr; //wie im oberen beispiel
    
    class MyClass;
    typedef std::string (MyClass::*MemFunPtr)(); //Typedef für den gleichen membefunktionstyp wie oben...
    
    void f(MemFunPtr ptr) { //diese Funktion nimmt einen memberfunktionspointer vom obigen Typ
      MyClass c;
      cout << c.ptr() << endl; //führt die Funktion, auf die ptr Zeigt, für das Objekt c aus und gibt das ergebnis an cout.
    }
    
    class MyClass {
    public:
      std::string fun1() {return std::string("lol");}
      std::string fun2() {return "rofl";}
      std::string fun3(char c = 'c') {return std::string(c);}
    }
    
    int main() {
      f(&MyClass::fun1); //OK, gibt lol aus
      MemFunPtr mfptr = & MyClass::fun2; 
      f(mfptr); //OK, gibt rofl aus
      f(&MyClass::fun3); //ERROR: fun3 hat die falsche Signatur, compiler bemängelt sowas wie "cannot convert std::string(*)(char) to std::string(*)()"
    }
    

    So, genug rumgespielt, ich denke das sollte es dir klarmachen 🙂



  • hmm wobei wir das ja wie schon in anderen Thread gesagt schon 1000x bald hatten 🙂
    Und davon mal abgesehen ... finde es immer etwas doof, wenn ihr da MyClass oder so hinschreibt. Das ist so zwar korrekt, aber da könnte auch MyStruct stehen ... geht damit ja genauso. struct und class sind in C++ nunmal identisch, mit der Ausnahme, dass sich die default-access-Art ändert ^^ d.h. bei struct public und bei class private.

    Hatte auch beim letzten mal ein kleines Template dafür gepostet ... dass das alles schön verpackt, so das ihr damit nichts zu tun habt.


Anmelden zum Antworten