Pointer auf Funktionen einer Klasse übergeben



  • Hallo,

    ich habe folgendes Problem:

    #ifndef KLASSEH
    #define KLASSEH
    
    typedef int tKLASSE (void); 
    typedef tKLASSE* tpKLASSE; 
    
    class klasse
    {
    public:
    
    	int x;
    
    	int f1();
    
    	tpKLASSE GetAdress();
    };
    
    #endif
    
    tpKLASSE klasse::GetAdress()
    {
    	return &klasse::f1;
    }
    

    Jetzt kommt der Fehler:
    Error 1 error C2440: 'return' : cannot convert from 'int (__thiscall klasse::* )(void)' to 'tpKLASSE'

    Wieso kommt dieser Fehler?
    Er ist weg wenn f1() static ist, aber genau das darf es in meinem Projket nicht sein?

    Danke!



  • f1 ist eine Methode der Klasse klasse, daher stimmt deine Typdefinition für tKLASSE nicht. Richtigerweise muss es heissen:

    typedef int (klasse::*tpKLASSE)(void);
    

    Edit: Typo fixed



  • Hi,

    sorry aber das war es auch nicht.
    Hab jetzt vieles probiert und irgendwo is da der Wurm drin.

    Also mein Projekt sieht so aus:

    Klasse, von der ich eine Funktion, die f1() benutzen will.

    Header:

    #ifndef USEDCLASSH
    #define USEDCLASSH
    
    class UsedClass
    {
    
    public:
    
     int f1();
    };
    
    #endif
    

    CPP:

    #include "UsedClass.h"
    
    int UsedClass::f1()
    {
    	return 7;
    }
    

    KLasse, die die Funktion f1() benutzt:

    Header:

    #ifndef USINGCLASSH
    #define USINGCLASSH
    
    #include "UsedClass.h"
    
    class UsingClass
    {
    
    public:
    
    	UsingClass(int (UsedClass::*Methode)());
    	int UsePointer();
    
    private:
    
    	int (UsedClass::*ptMethode)();
    
    };
    
    #endif
    

    CPP:

    #include "UsingClass.h"
    
    UsingClass::UsingClass(int (UsedClass::*Methode)())
    {
    	this->ptMethode = Methode;
    }
    
    int UsingClass::UsePointer()
    {
    	int x = this->ptMethode();
    	return x;
    }
    

    Main:

    #include <iostream>
    #include "UsingClass.h"
    #include "UsedClass.h"
    
    using namespace std;
    
    int main(void)
    
    {
    	UsedClass P;
    	UsingClass R(&UsedClass::f1);
    
    	int z = R.UsePointer();
    
    	return 0;
    }
    

    Ich werd noch wahnsinnig 🙂

    Danke.



  • int UsingClass::UsePointer()
    {
        int x = (this->*ptMethode)();
        return x;
    }
    

    oder gleich:

    int UsingClass::UsePointer()
    {
        return (this->*ptMethode)();
    }
    

    Aber du solltest das nächste mal den Fehler genau beschreiben, den du bekommst.

    Siehe auch hier:
    http://www.newty.de/fpt/index.html



  • Danke erstmal,

    habe nun die Änderungen vorgenommen und es kommt nun folgender Fehler:

    error C2064: Ausdruck ergibt keine Funktion, die 0 Argumente übernimmt

    an der Stelle

    int UsingClass::UsePointer()
    {
        int x = this->*ptMethode(); //C2064
        return x;
    }
    


  • Wo sind denn meine Klammern hin?



  • Sorry erstmal wegen der Klammern.

    Aber jetzt kommt anderer Fehler:

    Fehler 1 error C2440: 'newline': 'UsingClass *const ' kann nicht in 'UsedClass *const ' konvertiert werden
    Fehler 2 error C2647: '->': 'int (__thiscall UsedClass:: )(void)' kann nicht in 'UsingClass *const ' dereferenziert werden

    in:

    int UsingClass::UsePointer()
    {
        int x = (this->*ptMethode)(); //C2440 und C2647
        return x;
    }
    

    Ich versteh das alles nimmer, bin für jede Hilfe dankbar.



  • Da bist du wohl mit den beiden Klassen 'UsingClass' und 'UsedClass' durcheinandergekommen...



  • Ja. Da habe ich den Code nicht ganz angeschaut. 😉

    Du kannst die Funktion natürlich nur auf einen Zeiger der Klasse anwenden, von der auch der Zeiger ist.

    Das hätte dir auch auffalen können, da du ja eine Klasse UsedClass anlegst, aber nirgends benutzt.

    So z.B:

    int UsingClass::UsePointer()
    {
       UsedClass p;
       UsedClass* pp = &p;
       return (pp->*ptMethode)();
    }
    

    Macht aber natürlich nicht viel Sinn. Besser du übergibst UsingClass einen Zeiger auf das Objekt, auf das es den Funktionszeiger anwenden soll.



  • Danke,

    es klappt jetzt 👍 . Huh 😉 .



  • Wie gesagt. Wenn du jetzt einfach mein Beispiel kopiert hast, dann macht das überhaupt keinen Sinn und du kannst auch gleich eine normale Funktion nehmen.

    Wenn du allerdings eine Funktion auf eine bestimmte Instanz eines Objektes aufrufen willst, dann musst du den Zeiger von der main in die Klasse UsedClass übergeben, speichern und bei Bedarf für den Funktionsaufruf benutzen.

    Am Rande sei hier nocht boost::function erwähnt, mit welcher man das ganze sehr schön verpackt hat und unabhängig ob es eine freie Funktion oder eine Memberfunktion ist benutzen kann.


Anmelden zum Antworten