suche nach Mechanismus zur Kommunikation zwischen Klassentypen.



  • Hallo,
    ich beschreibe kurz was ich erreichen möchte:

    Es gibt 3 oder mehr Klassen

    class
    
    class Timer
    
    class EventHandler
    

    ich möchte in einer oder mehreren memberFunktionen der Klasse Application
    die MemberFunktion

    getTime()
    

    aus der Klasse Timer nutzen.
    Ausserdem möchte ich die gleiche Funktion auch in einigen Memberfunktionen der Klasse

    EventHandler
    

    nutzen.
    Und einige memberFunktionen der

    EventHandler
    

    Klasse auch wieder in der

    Application
    

    Klasse.

    Natürlich sind alle genannten Funktionen public.
    Und natürlich sollen die Objecte der Klassen nicht global sein.

    Ich hatte bis jetzt fogende Ansätze:
    Man könnte einfach in jeder Klasse in der z.B. eine Funktion der Klasse Timer benötigt wird ein solches Object erzeugen und benutzen.

    Man könnte alle Klassen die die Funktionalität von Timer brauchen, von Timer erben lassen.

    Beim ersten habe ich das Problem das ich Daten doppelt und vielfach habe.

    Beim zweiten habe ich nachher ein Klasse die vielleicht von 10 anderen erben muss. Scheint mir nicht der richtige Weg zu sein.

    Es heißt ja das das OO programmieren das versenden von Nachrichten zwischen Objecten ist.
    Leider weiß ich nicht wie ich so ein Mechanismus ins Programm reinbekomme.

    Es wäre super wenn ich von der Application Klasse einen Aufruf machen könnte z.B.

    requestTime()
    

    und die Klasse die diese nachricht verstehen kann, darauf darauf die dazugehörige Funktion ausführt und an die anfragende zurückgibt.

    Mir ist klar das es eine Nachrichten verwaltende Klasse geben muss aber ich habe keine Idee wie das alles zusammenhängen muss.

    Wenn jamand helfen könnte wäre ich dankbar.
    Muss auch kein Aufsatz sein wie der hier. 😉

    Gruß



  • in C++ ist das von dir genannte "nachrichten Versenden" schlicht und einfach das Aufrufen von Methoden der Empfängerklasse. Wenn in der (recht abstrakt gehaltenen) Literatur über Objektorientierte Programmierung im allgemeinen etwas steht wie "Ein Objekt a der Klasse A schickt einen Nachricht XY an das Objekt b der Klasse B" dann heißt das in C++ ganz einfach

    //irgendwo in einer Methode von A
    b.XY();
    

    Was deine Dreiecksbeziehung angeht:
    um getTime() zu benutzen brauchst du allerdings entweder ein Objekt vom Typ Timer, oder zumindest eine Referenz (bzw. einen Zeiger) auf ein solches Objekt. Es sei denn, getTime() ist static, dann reicht einfach ein Aufruf der Form Timer::getTime()
    Es kommt jetzt auf die Programmlogik und die Semantik der getTime()-Methode an, ob sich die Objekte jeweils ein unabhängiges Timer-Objekt erzeugen können oder ob die benutzten Timer-Objekte voneinander abhängig sein müssen (also das selbe Objekt oder Kopien des selben Objektes). Außerdem ist es eine Designentscheidung, ob sich die Objekte von Application und EventHandler die ganze Zeit ein eigenes Timer-Objekt halten (als Member), ob sie die ganze Zeit eine Referenz (oder Zeiger) auf ein externes Timer-Objekt halten, oder ob es sinnvoller ist, dass sie sich nur an den Stellen wo eins benötigt wird (innerhalb der Methoden) ein eigenes Objekt erzeugen bzw. es sich beim Aufruf der fraglichen Methoden einfahc mit übergeben lassen.

    /edit: Erben ist mit ziemlicher Sicherheit nicht die richtige Entscheidung. öffentliches Erben bedeutet immer eine "Ist-ein"-Beziehung, also "Eine Application ist ein Timer", "Ein EventHandler ist ein Timer". Privates bzw. geschütztes Erben macht allgemein nur dann Sinn, wenn der Timer protected Elemente hat, auf die die erbende Klasse Zugriff braucht (was dann bedeutet, dass der Timer für eine solche Art der Vererbung designt ist).



  • Man kann das mit den Messages auch so machen, wie es die WinAPI macht.
    Da kann man Messages an ein Fenster senden und das Fenster kann dann die Messages auswerten (in einer Funktion, die vom System aufgerufen wird und die Parameter übergibt).
    Das praktische ist natürlich, dass der Sender und Empfänger sich überhaupt nich kennen müssen. Das ganze kannst du natürlich auch in einer eigenen Klasse simulieren, indem du ein paar Messages definierst und dann (das offensichtlichste) ein Singleton hast, dass dir die ganzen Messages speichert und an eine bestimme Funktion weiterleitet. Dort wertest du dann die Messages aus (oder nicht) und nach dem Aufruf werden vlt. bestimmte Messages von deiner Klasse ausgewertet.



  • vielen dank,
    das hilft meinem Verständnis etwas weiter.

    @drakon: könntest du es noch genauer umschreiben, wie ich das konkret machen sollte - anhand meiner 3 Klassen - an genau so ein System wie Windows es hat habe ich nähmlich auch gedacht.
    Verstehe aber nicht wie es genau umzusetzten ist.
    Jede Funktion müsste ja so etwas wie eine ID bekommen. Diese ID Liste müsste dann jede Klasse kennen und damit etwas anfangen können. Es muss also eine Basisklasse geben die das kann und von der alle erben.
    Soweit meine Theorie - wie ich das umsetzte, steht irgendwo auf einem anderen Blatt.
    Also trau dich ruhig etwas näher darauf einzugehen. 😉

    @pumuckl:

    static
    

    ist ein gutes Stichwort - thx.



  • Ne. Das läuft eher darauf hinaus, dass du irgenwo Funktionszeiger speicherst, die eine bestimmte Schnittstelle anbieten müssen. Dann kannst du die einfach in (z.B) Singleton in einer Liste speichern und dann jede Funktion durchen und aufrufen.

    class Manager : Singleton<Manager>
    {
     void Register ( int (*fp)(int,...) )
     {
       functions.push_back ( fp );
     }
    
     list<FunctionPointerType> functions;
    };
    ...
    
    int AppFunc ( int message,...)
    {
     switch (message)
     {
       case MYWM_CLOSE:
        Shutdown;
        break;
     }
    ...
    }
    
    ...
    
    Manager::Register ( &AppFunc );
    

    So in etwa. Natürlich kannst du das auch noch ein wenig anderst machen und dir Memberfunktionen merken, anstatt normale Funktionen.



  • ja vielen dank das hilft weiter.




Log in to reply