kompletter zeiger auf member-funktion



  • ich habe das problem, das ich ums verrecken keinen zeiger auf eine memberfunktion der instanz einer klasse zuweisen kann. bei dem versuch meckert der compiler immer "iso c++ forbids..." blabala. das muss technisch auf jeden fall möglich sein ,also soll er es auch tun. wenn ich dieses verhalten mit irgenteiner kompileroption(ich verwende mingw) abschalten kann, gerne.

    beispiel (die stellen, an denen ich nicht weiss, wie ich es ausformulieren
    soll sind auskommentiert):

    class Test
    {
    	private:
    		int wert;
    
    	public:
    		Test(int w);
    		void gibAus(void);
    };
    
    Test::Test(int w)
    {
    	wert=w;
    }
    
    void Test::gibAus(void)
    {
    	std::cout << wert << std::endl;
    }
    
    int main()
    {
        Test  *a, *b;
        // zeigerdeklaration??? *z1, *z2,
    
        a=new Test(34);
        b=new Test(912);
    
    	z1=//?? zuweisung der adresse von a->gibAus();
    	z2=//?? zuweisung der adresse von b->gibAus();
    
    	//aufruf der funktionen
    	z1();
    	z2();
    
    	//ausgabe:34, 912
    
        delete b;
        delete a;
    }
    

    es soll zum schluss halt EINE zeigervariable sein, die ich dann ohne umstände ansprechen kann. wie kann ich das hinkriegen?

    hintergrund:
    ich habe in meinem echten programm viele völlig verschiedene objektinstanzen mit ebenso unterschiedlichen memberfunktionen, welche ich über eine grafische steuerung(eine art virtuelle konsole mit knöpfen) ansprechen will. jedem virtuellen knopf ist dann z.b. eine memberfunktion irgenteines objktes zugeordnet. die einfachste art ist halt, beim ersten rendern(wenn die 2d-koordinaten bekannt sind) jedem mausklick ihre entsprechende memberfunktion zuzuordnen.



  • tenim schrieb:

    ich habe das problem, das ich ums verrecken keinen zeiger auf eine memberfunktion der instanz einer klasse zuweisen kann. bei dem versuch meckert der compiler immer "iso c++ forbids..." blabala. das muss technisch auf jeden fall möglich sein ,also soll er es auch tun.

    Nein, das ist technisch eben nicht möglich. Funktionszeiger sind direkt nur für Funktionen und statische Methoden (Memberfunktionen) möglich. Nicht-statische Methoden erfordern zwei Zeiger:
    1. Den Zeiger auf die Instanz (a->foo())
    2. Den Zeiger auf die Methode (a->foo())

    Edit: Um es dir vielleicht mal zu verdeutlichen, sei hier auf den this-Zeiger in Methoden verwiesen. Dieser this-Zeiger muss gegeben sein (Das ist der Instanzzeiger). Du kannst dir (stark vereinfacht) eine Methode "void Bar::Foo()" wie eine Funktion "void Foo(Bar * this)" vorstellen.

    tenim schrieb:

    es soll zum schluss halt EINE zeigervariable sein, die ich dann ohne umstände ansprechen kann. wie kann ich das hinkriegen?

    In dem du nicht Funktionszeiger, sondern Funktionsobjekte (sogenannte Funktoren) verwendest. Ich verweise hier auf boost::function und boost::bind (bzw. auf deren TR1 Gegenstücke std::tr1::function und std::tr1::bind).

    cu André



  • das verstehe ich nicht. im endeffekt beinhaltet ein funktionszeiger doch nur eine adresse auf eine speicherstelle im ram, ab dem sich ausführbarer code befindet. und das ist der einsprungpunkt der memberfunktion. der muss sich ja auch irgentwo im ram befinden.

    verstest du was ich meine? es ist doch im endeffekt völlig egal, wie viele klassen/ objekte wasweisich geschachtelt oder vererbit irgentwo liegen. im endeffekt spreche ich immer den einsprunkpunkt einer gewissen funktion im ram an.
    (auf unterster ebene gesehen).



  • tenim schrieb:

    das verstehe ich nicht. im endeffekt beinhaltet ein funktionszeiger doch nur eine adresse auf eine speicherstelle im ram, ab dem sich ausführbarer code befindet. und das ist der einsprungpunkt der memberfunktion. der muss sich ja auch irgentwo im ram befinden.

    Die Methode Test::gibAus liegt aber nur einmal im Speicher. Der Code wird nicht für jede Instanz dupliziert.



  • verstehe. und wenn sich dann in dieser einen kopie der memberfunktion auf ein objekt ausserhalb bezogen wird, kann er nicht wissen, zu welcher objektinstanz. deshalb braucht er ausserdem den objektzeiger.



  • tenim schrieb:

    das verstehe ich nicht. im endeffekt beinhaltet ein funktionszeiger doch nur eine adresse auf eine speicherstelle im ram, ab dem sich ausführbarer code befindet. und das ist der einsprungpunkt der memberfunktion. der muss sich ja auch irgentwo im ram befinden.

    verstest du was ich meine? es ist doch im endeffekt völlig egal, wie viele klassen/ objekte wasweisich geschachtelt oder vererbit irgentwo liegen. im endeffekt spreche ich immer den einsprunkpunkt einer gewissen funktion im ram an.
    (auf unterster ebene gesehen).

    Du weisst ja bestimmt, dass Instanzen einen this -Zeiger haben.
    Im Prinzip kannst Du Dir nichtstatische Memberfunktionen als statische Memberfunktionen vorstellen, die immer automatisch den this-Zeiger für die aktuelle Instanz als erstes Argument mitbekommen.
    Wenn Du nun Funktionszeiger auf nichtstatische Memberfunktionen anlegst, dann musst Du irgendwie immer auch die Instanz beisteuern, auf die sich die Memberfunktion bezieht.



  • Funktionszeiger auf nicht-statische Methoden sind in C++ moeglich, auch wenn es durch die anderen Post nicht so scheint. Aber um eine solche Methode aufzurufen, musst du immer noch ein Objekt mitliefern.
    siehe: http://www.parashift.com/c++-faq-lite/pointers-to-members.html


  • Administrator

    knivil schrieb:

    Funktionszeiger auf nicht-statische Methoden sind in C++ moeglich, auch wenn es durch die anderen Post nicht so scheint. Aber um eine solche Methode aufzurufen, musst du immer noch ein Objekt mitliefern.
    siehe: http://www.parashift.com/c++-faq-lite/pointers-to-members.html

    Du solltest die Beiträge, welche vor dir geschrieben wurden, genauer lesen 😉
    Ansonsten helfen übrigens Brillen oder Kontaktlinsen. Es ist unglaublich wie viel schärfer die Welt aussieht, seit ich meine Brille habe 😃

    Grüssli



  • Dravere schrieb:

    Du solltest die Beiträge, welche vor dir geschrieben wurden, genauer lesen 😉
    Ansonsten helfen übrigens Brillen oder Kontaktlinsen. Es ist unglaublich wie viel schärfer die Welt aussieht, seit ich meine Brille habe 😃

    Grüssli

    Ich habe schon richtig gelesen. Ich differenzierte zwischen dem Abspeichern eines Methodenzeigers und der tatsaechlichen Benutzung. Fuer ersteres braucht man nur einen Zeiger und fuer letzteres benoetigt man noch ein Objekt. So wurde es in den vorherigen Post nicht dargestellt bzw. differenziert. Konkret bezog ich mich auf:

    Nein, das ist technisch eben nicht möglich. Funktionszeiger sind direkt nur für Funktionen und statische Methoden (Memberfunktionen) möglich. Nicht-statische Methoden erfordern zwei Zeiger: ...



  • knivil hat voll und ganz Recht.
    Hier nochmal was auf deutsch: http://tutorial.schornboeck.net/meth_zeiger.htm

    Zeiger auf Memberfunktionen sind moeglich - allerdings ist fuer den Aufruf eine Instanz der Klasse noetig; fuer diesen kannst (oder musst) du ebenfalls einen Zeiger erstellen, wenn du das ganze erst zur Laufzeit festlegen willst 🙂

    Gruss
    Cartman


  • Administrator

    Ihr solltet wirklich beide nochmals die Beiträge lesen. Es hat niemand behauptet, dass dies nicht möglich sei!
    Nur ist das, was der OP machen will nicht möglich. Diese Beiträge da oben haben einen Zusammenhang, die stehen da nicht einfach nur einzeln rum!

    🙄

    Grüssli


Log in to reply