Methodenpointer



  • Hallo zusammen!

    Beiträge zum Thema Pointer auf Klassenmethoden existieren ja
    bereits im Forum. Trotzdem bleiben für mich, was dieses Thema
    anbelang, noch ein paar Fragen offen. Wäre schön, wenn mir jemand
    bei der Beantwortung der folgenden Fragen behilflich sein könnte.

    Letztendlich ergeben sich für mich noch genau 2 Unklarheiten:
    Problem 1:
    ----------

    Ich würde zum einen gerne Pointer auf Klassenmethoden in einer
    LinkedList ablegen.
    d.h.:
    der Konstruktorenaufruf könnte z.B. so aussehen:
    LinkedList<void (ClassName::*)(void)> list();

    Und nun der Knackpunkt:
    ich gebe ja bei diesem Aufruf als TemplateParameter den Zeigertyp
    auf Methoden der Klasse 'ClassName' mit der o.g. Struktur an.

    Diese Vorgehensweise könnte ich ja jetzt, z.B., mit dem Ablau vergleichen, der
    erforderlich wäre, um eine LinkedList für 'ClassName'-Objekte zu erzeugen.
    also:

    a) LinkedList<ClassName *> list();

    ein Aufruf auf folgende Art und Weise wäre ja ebenfalls gültig
    (ich müsste nur die LinkedList intern anpassen):

    b) LinkedList<ClassName> list();

    Und hier liegen meine Schwierigkeiten!

    -->
    Ist eine Behandlung der LinkedList, so wie Sie unter b) geschehen ist,
    auch bei den Klassenmethoden möglich?
    Soll heissen:
    kann ich bei dem Aufruf:
    LinkedList<void (ClassName::*)(void)> , bei dem ich ja einen Pointertyp
    angebe, auch einen Klassenmethodentyp angeben?
    ==> wie sieht denn dann die Syntax aus?

    Problem 2:
    ----------

    In diversen Beiträgen im Forum wurde ja schon erwähnt, dass bei einem
    Aufruf einer Klassenmethode immer das Binden an ein konkretes Objekt erforderlich ist.
    d.h.:
    entweder z.B. ausserhalb des Objekts so: (object->*object->methodPtr)();

    oder innerhalb des Objekts so: (this->*this->methodPtr)();

    Bei diesem Ansatz wird aber immer davon ausgegangen, dass der MethodenPointer
    als Attribut von 'object' vorliegt.

    Was ist denn aber nun, wenn mir ausserhalb des Objekts ein Pointer auf eine
    bestimmte Klassenmethode vorliegt!
    Wie rufe ich denn dann die Klassenmethode auf?
    Wie binde ich denn jetzt die Methode an das Objekt?

    Wäre schön wenn mir jemand auf die Sprünge helfen könnte!

    Danke,
    TS++



  • Guck mal in die FAQ 😉



  • OK!
    Punkt Nummer 2 hat sich erledigt!
    Nur was Problem Nummer 1 anbelangt, bin
    ich leider immer noch nicht weiter!

    Kann mir jemand helfen, auch noch dieses Übel zu
    beseitigen?

    Danke,
    TS++



  • also mit std::list

    #include <list>
    using namespace std;
    
    class foo
    {
    public:
        void f1() {}
        void f2() {}
    };
    
    int main()
    {
        typedef void (foo::*mem_func_ptr)(); // nicht notwendig aber schöner
        list<mem_func_ptr> bla;
        bla.push_back( &foo::f1 );
        bla.push_back( &foo::f2 );
    
        foo f;
        for(list<mem_func_ptr>::iterator i = bla.begin(); i != bla.end(); ++i)
            (f.*(*i))()
    }
    


  • Und wenn er auch Methoden-Zeiger verwalten will die von anderen Klassen als foo kommen? :p 🙂



  • Erst einmal vielen Dank für eure Antworten!

    Aber:
    Vielleicht hab ich mich ja , was Problem Nummer 1 anbelangt,
    etwas unklar ausgedrückt.

    Syntax der Form:

    typedef void (foo::*mem_func_ptr)();
    list<mem_func_ptr> bla;

    bzw.:

    list<void (foo::*)()> bla;

    ist mir bekannt!

    Jedoch gebe ich nach wie vor als Templateparameter einen
    Methoden-POINTER-Typ an. Mich würde interessieren, ob es
    auch möglich ist einen Methodentyp anzugeben(keinen Ptr).
    Bei einer ganz normalen Klasse funktioniert's ja auch:

    list<ClassName *> list() oder list<ClassName> list()

    je nachdem, was die LinkedList erwartet.
    Ich sehe auch in entsprechender Literatur immer nur die Syntax
    für Methodenpointer,
    also: Rückgabewert (Klassenname::*)(Parameter)
    aber niemals die, für einen Methodentypen.

    Existiert ein derartiges Konstrukt vielleicht gar nicht oder
    ist ein Denkfehler verantwortlich?

    Bitte durchhalten! 😉

    Grüße,
    TS++

    [ Dieser Beitrag wurde am 27.03.2003 um 18:31 Uhr von TS++ editiert. ]



  • Ich denke nicht, das hieße ja, Du würdest die Funktion in die Liste stecken. In C++ sind Funktionen aber keine Objekte, man kann sie nicht kopieren oder löschen oder sowas. Insofern kann ich mir auch nicht vorstellen, daß man sie auf diese Art in Container stecken könnte.



  • was du suchst sind binder

    #include <list>
    using namespace std;
    
    class foo
    {
    public:
        void f1() {}
        void f2() {}
    
        typedef void (foo::*mem_func_ptr)();
    };
    
    class bar
    {
    public:
        bar(foo * instanz, foo::mem_func_ptr func)
            :    instanz_( instanz ),
                 func_( func )
        {
        }
    
        void operator() ()
        {
            (insatnz_->*func_)();
        }
    private:
        foo * instanz_;
        foo::mem_func_ptr func_;
    };
    
    int main()
    {
    
        list<bar> bla;
    
        foo a;
        bla.push_back( bar( &a, &foo::f1) );
    
        foo b;
        bla.push_back( bar( &b, &foo::f2) );
    
        for(list<bar>::iterator i = bla.begin(); i != bla.end(); ++i)
            (*i)();
    }
    


  • Vielen Dank!
    Damit wäre ich für den Moment wunschlos glücklich.

    -> Die Idee, Methoden- und ObjektPointer zu kapseln
    und erst dann in die LinkedList einzufügen kann ich
    gut verwenden! 😃

    Wär doch mit Sicherheit auch noch ne gute Idee, die Klasse 'bar'
    als Template-Klasse zu schreiben und diese dann von einem Interface
    'SuperBar' abzuleiten. Dann könnte ich einmal Methoden- und Objektpointer
    beliebiger Klassen in 'bar'-Objekten kapseln und diese dann, da 'bar'-Objekte
    ja auch 'SuperBar'-Objekte sind, als 'SuperBar'-Objekte in die LinkedList
    list<SuperBar> bla einfügen.
    ==> Dann könnte ich ja jedem Listeneintrag von 'bla' z.B. den Befehl 'execute()'
    zuweisen und das jeweilige 'bar'-Objekt könnte dann die referenzierte Methode
    an das betroffene Objekt binden und die Methode ausführen.
    Mal schaun ob's funtzt! 😉

    Vielen Dank für eure Hilfe!

    Grüße,
    TS++



  • tja, das funzt soweit, nur das es dann nur mit SuperBar Pointern geht

    list<SuperBar*> bla



  • Stimmt!
    Für die LinkedList, die ich in meinem CodeBeispiel verwendet habe,
    muss ich einen PtrTyp angeben. Darauf hab ich gar nicht geachtet.

    Aber was ist denn, wenn ich die LinkedList selber schreibe. Wie meine
    eigene Liste bestimmte Templateparameter interpretiert, ob Objekt- oder
    Ptrtyp, kann ich doch steuern, oder?!

    Ich denke dann müsste die Syntax korrekt sein!

    Grüße,
    TS++



  • Original erstellt von <bjarne>:
    **tja, das funzt soweit, nur das es dann nur mit SuperBar Pointern geht

    list<SuperBar*> bla**

    Ja und? execute() kann er dann doch zur Not virtuell machen und in bar redefinieren



  • ach lass mich doch in ruhe :o


Anmelden zum Antworten