Objekt erstellen und weitergeben?



  • Abgeleitet von http://www.c-plusplus.net/forum/308501 , da ich da wohl zu unübersichtlich beiträge gepostet habe, dachte ich ich fange doch ein neues an für die letzte Frage dort..

    Ich möchte ein Objekt erstellen, und aus einer anderen Klasse auf das Objekt zugreifen, wie stell ich das am besten an?

    - Ein Objekt generieren in CGameInit

    CGame game;
    game.Init();
    

    - Diese Objekt weiterverwenden in CPlayer

    CGame game; //hier, wie krieg ich irgendwie mit, welches Objekt ich schon in der CGameInit habe? so mache ich doch eifnach ein neues objekt und das weis halt nix vom alten...
    game.draw(player);
    

    Ich mache am anfang meines Codes ein Objekt von der CGame, mit dessen Objekt ich dann ein Fenster generiere, und diese Fenster brauch ich dann ja weiter von der CPlayer init, auch WENN player halt nich wissen muss welches Fenster ich habe, damit ich vom CPlayer aus auf das Fenster zugreifen kann, muss ich ja wissen welches Objekt das Fenster kreiert hat damit ich darauf zugreifen kann...

    auch wenn ich das Fenster erst später generier, oder in einer Seperaten Klasse, ich komme immer an einen Punkt wo 2 Klassen auf dasselbe Objekt zugreifen müssen, woher wissen die welches Objekt ich meine?



  • In dem du entweder game global definierst oder deinem CPlayer-Konstruktor einen Pointer auf deine alte Variable mit gibst und diese da verwendest.

    Mfg veeman


  • Mod

    Dein Beitrag krankt wieder an den schon von mir genannten Symptomen, dass niemand, der nicht den gesamten anderen Thread gelesen hat, eine blasse Ahnung hat, was du überhaupt wissen möchtest. Was ist ein CGame, ein Cplayer, ein CGameInit? Warum haben die alle ein C? Was sollen diese ganzen init-Mathoden? Schon einmal von Konstruktoren gehört? Was soll ein CGameInit modellieren? Das klingt, als würdest du eine Funktion in eine Klasse quetschen, weil du mal gehört hast, dass alles eine Klasse sein soll. Richtig geraten?

    Deine einzige konkrete Frage macht eben aus diesem Grunde auch keinen Sinn:

    Flutscherino schrieb:

    Ich möchte ein Objekt erstellen, und aus einer anderen Klasse auf das Objekt zugreifen, wie stell ich das am besten an?

    Eine Klasse macht nichts, auch keine Zugriffe. Eine Klasse ist ein Backrezept mit dem man Instanzen dieser Klasse erstellen kann. Meinst du eine Methode einer Instanz dieser Klasse soll auf ein anderes Objekt zugreifen? Dann übergib es ihm einfach.

    Aber ich fürchte du denkst dir eher so etwas wie

    GameInit initiator;
    Game game;
    initiator.init(game);
    initiator.execute();
    // game ist nun initialisiert
    

    Da kann ich nur zu sagen: Mach das nicht. Sehr schlechter Modellierungsansatz (für C++. Und einige Leute sagen auch allgemein). Wir sind hier nicht in Java, in C++ darf man Funktionen benutzen.

    Um konkreteren Rat zu geben, müsste man wissen, was deine Klassen sind, wie sie zueinander in Beziehung stehen, was sie machen sollen und warum das alles so ist wie es ist.



  • Hmm wie kann ich das besser erklären ohne mein ganzen code hier zu posten? denn ich denk nich das ihr das alles lesen wollt ^^

    Naja, wie schon vorher besteht mein Projektchen jetzt aus ner Map, nem Spieler und ner Game Klasse, und gestartet wird in der main(), was auch gleich in die Game Klasse einsteigt.

    main
    ---
    macht ein CGame Objekt um die Init darin aufzurufen

    CGame Init
    ---
    erstellt das Fenster.
    erstellt den Spieler CPlayer
    führt dann Run() aus.

    CGame Run
    ---
    Ruft dann auf welche Tasten gedrückt sind. CPlayer->Move()

    CPlayer
    ---
    CPlayer muss ja wissen
    - welches Fenster ich habe
    - welches Objekt welches Fenster erstellt hat
    - ?

    egal wie ich es drehe oder wende, irgendwo bin ich an einem Punkt da ich wissen welches Objekt erstellt wurde in der main ODER welches Fenster ich benutze, und genau da häng ich.
    Wie mache ich der CPlayer klasse klar, das eben das Objekt genommmen werden soll was schon in der main() erstellt wurde?

    Wie meine Klasse ja aussehn is nicht wichtig, oder?

    ich weis, irgendwie ist die frage glaube ich ziemlich doof, aber ich komm einfach nich weiter wie ich das angehn soll... 😕



  • Wenn ein Objekt A mit Objekt B arbeiten soll, musst du Objekt A eine Referenz von Objekt B übergeben. Entweder schon im Konstruktor oder später nach der Erstellung der Instanz per Methode.

    Es gebe noch die Möglichkeit ein globales statisches Objekt zu erstellen, was dann in jeder Klasse sichtbar wäre, aber dies ist in der Regel schlechter Code da schwer durch zu blicken ist.


  • Mod

    Wieso muss ein Player was von Fenstern wissen? Entweder haben deine Klassen fehlleitende Namen oder sie machen Sachen, die sie eigentlich gar nichts angehen.



  • Das war nicht die Frage des Threaderstellers.



  • Hier etwas Code, da kannst Du Mal sagen, ob Dir das reicht oder nicht. Wenn nicht, wieso nicht?

    class CGame
    {
    // ...
    };
    
    class CPlayer
    {
    public:
        CPlayer(CGame& game) : game(game) {}
    // ...
    
    private:
        CGame& game;
    };
    

    Im Constructor von CPlayer, kannst Du jetzt das Game übergeben und es ist fortan innerhalb aller CPlayer-Methoden als game bekannt. Tadaa!

    Nein?

    PS: Allen Codingconventions, die von SeppJ und co. vorgeschlagen wurden, stimme ich selbstverständlich zu, denn die sind gut.


  • Mod

    ErstLesendannSchreiben schrieb:

    Das war nicht die Frage des Threaderstellers.

    Das ist aber das, was ihm weiterhilft, wenn er die Hilfe nur annähme.



  • Man sollte Referenzen nicht als Member halten.



  • jkjkjjk schrieb:

    Man sollte Referenzen nicht als Member halten.

    stimmt, das ist unter jeden Umständen immer und absolut ohne Ausnahme ein schwerer Fehler.

    PS: Wer Ironie findet, darf sie behalten.



  • jkjkjjk schrieb:

    Man sollte Referenzen nicht als Member halten.

    Wieso nicht?


  • Mod

    daddy_felix schrieb:

    jkjkjjk schrieb:

    Man sollte Referenzen nicht als Member halten.

    stimmt, das ist unter jeden Umständen immer und absolut ohne Ausnahme ein schwerer Fehler.

    PS: Wer Ironie findet, darf sie behalten.

    Es ist aber sehr oft ein Fehler und sehr ungewöhnlich, wenn man es als Lösung empfiehlt. Meistens ist das, was man dadurch modelliert nämlich nicht das, was gemeint ist. Ich habe jedenfalls nicht den Eindruck, dass das was eine Memberreferenz ausdrückt hier gemeint ist. (Ich bin auch der Meinung ein Pointer wäre hier falsch und der Threadersteller sollte alles nochmal ganz neu machen, aber ein Pointer drückt auf jeden Fall besser aus, wonach er hier gefragt hat (aber nicht das, was ihm weiterhilft))


  • Mod

    Eisflamme schrieb:

    jkjkjjk schrieb:

    Man sollte Referenzen nicht als Member halten.

    Wieso nicht?

    Probier zum Beispiel mal aus, was die automatisch erzeugten Member genau machen. Außerdem: Was willst du damit modelliertechnisch ausdrücken? Absolute Verbundenheit bis in den Tod? Warum sind sie dann nicht gleich ein einziges Ganzes? Welche Vorteile hätte eine Referenz?

    Siehe auch die Diskussion, die hier beginnt:
    http://www.c-plusplus.net/forum/p2236581#2236581



  • Wie die anderen schon gefühlte 100x gesagt und ich auch im anderen Thread erwähnt habe ist dein Design komplett falsch. Jede Klasse tut nur genau das, wofür sie entworfen wurde, weiß nicht mehr, als sie wissen muss und delegiert alle Aufgaben, die nicht die ihren sind an die Klassen, die sich darum kümmern. Wenn dein Player (hör bitte mit den Präfixen auf, Ungarische Notation schafft mehr Unklarheit als Nutzen) einen Zeiger/Referenz auf dein Fenster braucht, untergräbst du damit den Sinn der OOP.

    Flutscherino schrieb:

    Ruft dann auf welche Tasten gedrückt sind. CPlayer->Move()

    CPlayer
    ---
    CPlayer muss ja wissen
    - welches Fenster ich habe
    - welches Objekt welches Fenster erstellt hat
    - ?

    Warum muss er das? Was macht die Methode move() genau?
    Kannst ja doch mal deinen gesamten Quelltext hier hineinkopieren, sodass man auch mal die Umgebung sieht, vielleicht ist ja dein Design vollständig für die Hose.



  • SeppJ schrieb:

    ]Es ist aber sehr oft ein Fehler und sehr ungewöhnlich, wenn man es als Lösung empfiehlt.

    klar, das bestreite ich ja auch gar nicht. Nur sträube ich mich ein wenig dagegen, dies pauschal als falsch zu deklarieren.



  • Die Diskussion endete aber nicht und ich war am Ende auch nicht überzeugt. 🙂 Aber das muss hier ja auch nicht weiter diskutiert werden. In der Praxis ist eine Referenz zumindest meistens weniger praktisch.

    Insofern bitte mein Beispiel mit Pointer statt Referenz denken.

    Wenn ich demnächst Mal Zeit und Muße habe, spiel ich eine Klasse mit Referenzattributen Mal für copy, move etc. durch, um zu sehen, wo Probleme auftauchen könnten.



  • Wo lernt man sowas wie, keine Referenzen als Member nehmen? Oder wie erkenne ich dass mein Programm nicht richtig ausmodelliert ist.

    Ich kann etwas C++ und ein paar Design Pattern. Mit dem Wissen mache ich halt was. Zu warten bis ich C++ vollständig kann oder auch alle DPs richtig beherrsche, geht ja schlecht, denn man lernt nur durchs Entwickeln und nicht durchs Lesen oder Tutorial-Videos anschauen. Also lerne ich ein wenig und machen dann daraus was. Dann lerne ich was dazu und mache es beim nächsten Mal besser.

    Wenn ich auf alle Sachen achten würde,die hier so manchmal erwähnt werden, dann würde bei mir kein einziges Programm je fertig werden^^


  • Mod

    Butterbrot schrieb:

    Wo lernt man sowas wie, keine Referenzen als Member nehmen? Oder wie erkenne ich dass mein Programm nicht richtig ausmodelliert ist.

    Hier 🙂

    Wenn ich auf alle Sachen achten würde,die hier so manchmal erwähnt werden, dann würde bei mir kein einziges Programm je fertig werden^^

    Wieso? Klar kannst du Programme schreiben, ohne alles zu wissen (und wirst dabei klüger). Aber wenn du erst einmal etwas besser weißt, was hindert dich, dieses Wissen ab dann zu benutzen?



  • Butterbrot:
    Na ja, ich würde auch nicht jedes Programm komplett refactorn, aber für neue Projekte solltest Du es in Angriff nehmen. Und da Du mit Deinem Spiel jetzt ja erst anfängst, solltest Du es direkt so richtig wie möglich machen. Du denkst, das hält Dich auf, aber wenn Du wirklich bis zu dem Punkt die Dinge vernünftig machst wie hier beschrieben, hast Du Dir viel Lern-, Überarbeitungs- und Erweiterungszeit gespart. Du hast die tollen Dinge ja schon eingebunden, die wirst Du dann recht zügig verstehen (vermutlich) und kannst dann noch schneller noch mehr lernen.


Log in to reply