Kurze Frage zu Funktionszeigern



  • Hallo zusammen,

    ich habe wieder mal eine kurze Frage! 😉 🙄

    Und zwar habe ich z.B. eine Klasse zum Zeichnen
    von graphischen Objekten.

    Die Klasse enthält als private Membervariable u.a.
    einen Funktionszeiger auf eine Funktion, die das Zeichnen
    der Objekte übernimmt.

    Man kann also problemlos mehrere Funktionen verwenden,
    die das Zeichnen ganz unterschiedlich übernehmen.

    Das Problem dabei ist, dass falls kein Funktionszeiger übergeben
    wurde, der Zeiger auf eine Memberfunktion der Klasse zeigen soll
    (wird im Konstruktor der Klasse erledigt).

    Und genau da knallt es:
    error C2276: '&' : Ungueltige Operation auf Ausdruck einer gebundenen Member-Funktion

    Meine Frage ist jetzt:
    Warum ist diese Vorgehensweise nicht möglich.
    Wenn ich ein Objekt anlege, wird doch speicher reserviert.
    Warum in drei Teufelsnamen kann kein Funktionszeiger auf eine Memberfunktion
    zurückgegeben werden?????????

    Vielen Dank schon mal im Voraus,
    Markus



  • Hallo,

    sowas kann man immer besser mit Code verstehen.



  • Ok, mit code sieht das in etwa so aus:

    typedef void (*FPRESIZE)(int, int);
    typedef bool (*FPDRAW)();

    class Zeichnung{

    public:
    Zeinung();

    private:

    //Memberfunktionen der Klasse

    bool draw();
    void resize(int width, int height);

    //Funktionszeiger zu Funktionen evtl. ausserhalb der Klasse

    FPDRAW FuncDraw;
    FPRESIZE FuncResize;

    //Falls eine Memberfunktion zum Zeichnen verwendet werdne soll
    //zeichne die Polygone des Vektors (verwendet von draw())

    std::vector<TRIANGLE> polygones;

    };

    Zeichnung::Zeichnung(){

    //Falls keine externe Funktion zugewiesen wurde,
    //Zuweisung an die Memberfunktionen

    this -> FuncDraw = &draw; // hier kommt die Fehlermeldung
    this -> FuncResize = &resize; // hier kommt die Fehlermeldung

    }

    Gruß,
    Markus



  • Das merkwürdige ist halt,
    dass es mit allen Funktionen funktioniert, die keine
    Member von Zeichnung sind.
    Statisch machen will ich die Memberfunktionen auch nicht.
    Mal sehen wer dazu etwas sagen kann.

    Viel Grüße



  • Probier mal folgendes:
    Statt:

    FPDRAW FuncDraw;
    FPRESIZE FuncResize;
    

    Das:

    void (Zeichnung::*FuncResize)(int, int);
    bool (Zeichnung::*FuncDraw)();
    

    Und im Konstruktor:

    this->FuncResize = resize;
    this->FuncDraw = draw;
    


  • Sorry,

    so wie du es geschrieben hast habe ich es.
    Hab mich nur beim Einstellen ins Forum vertan.
    Aber wie gesagt, es funktioniert so nicht.

    Keine Ahnung warum!!!


  • Mod

    wenn ich mich recht erinnere sind functionspointer immer _cdecl wenn nicht anders deklariert. die zuzuweisende funktion muss dann nat. die gleiche aufrufkonvention benutzen, memberfunktionen benutzen aber thiscall, leider kann man diese nicht explizit deklarieren. oder man benutzt gleich etwas besseres wie stdcall oder fastcall. wenn du auch nichtmemberfunktionen zuweisen willst, solltest du das ganze aber lieber mit statischen memberfunktionen machen(dann brauchst du auch nicht unbedingt die aufrufkonvention zu ändern), etwa so:

    class Zeichnung
    {
    
    public:
    	Zeichnung();
    
    private:
    
    	typedef void (__fastcall *FPRESIZE)(Zeichnung*, int, int);
    	typedef bool (__fastcall *FPDRAW)(Zeichnung*);
    
    	//Memberfunktionen der Klasse
    
    	static bool __fastcall Draw(Zeichnung* pThis);
    	static void __fastcall Resize(Zeichnung* pThis, int width, int height);
    
    	//Funktionszeiger zu Funktionen evtl. ausserhalb der Klasse
    
    	FPDRAW FuncDraw;
    	FPRESIZE FuncResize;
    
    	//inline interface um Funktionen direkt mittels objekt.function benutzen zu können
    
    	inline bool draw() { FuncDraw( this ); }
    	inline void resize(int width, int height) { FuncResize( this, width, height ); }
    
    	//Falls eine Memberfunktion zum Zeichnen verwendet werdne soll
    	//zeichne die Polygone des Vektors (verwendet von draw())
    
    	std::vector<TRIANGLE> polygones;
    };
    
    Zeichnung::Zeichnung()
    {
    	//Falls keine externe Funktion zugewiesen wurde,
    	//Zuweisung an die Memberfunktionen
    	FuncDraw = &Draw;
    	FuncResize = &Resize;
    }
    

Anmelden zum Antworten