Problem mit Zugriffen
-
Ich hänge immer noch an meinem System:
class Game hat eine private Instanz von class Player.
class Player eine private Instanz von Inventory und
class Inventory welche von den Item-Klassen.Es ist ja bekannt, dass man keine Instanz global anlegen soll. Nur das stellt mich vor eine Wand:
Zunächst erstelle ich in main() ein Objekt von class Game, dann schreibe ich
game.init();So, jetzt möchten aber auch die Item-Klassen auf class Player zugreifen, um seine Eigenschaften zu verändern.
Das geht jetzt aber nur mit einem Objekt von Game.
Und das habe ich in main() schon erstellt.Wenn ich jetzt in Funktionen der Item-Klassen ein neues Objekt erstelle, habe ich alles doppelt, Player, Inventory usw...
Das möchte ich ja nicht...
Was kann ich tun?
//P.S.:
Ist es eigentlich soo schlimm, wenn ich eine einzige Instanz von meiner Hauptklasse Game erstelle?
Was für Gefahren würde es geben?Weil es könnten dann alle auf Game zugreifen, und die Instanz würde sowieso nur ein einziges mal erstellt werden, hmm...
-
etwas daran ändern, dass das nur mit einer object von Game möglich ist.
-
Es muss doch andere Möglichkeiten geben.
Wo soll ich sonst ein Objekt von Player definieren?
Dann habe ich ja erst noch mehr Instanzen...Ich möchte einfach überall im Projekt auf ein Objekt von Game zugreifen können, ohne es global zu definieren. Das Objekt soll immer dasselbe sein und bleiben. (Nur 1 Spiel, keine 2 ;))
Oder, wiegesagt, ist es überhaupt so schlimm (in meinem Fall), global zu definieren?
-
Innerhalb von Game ist schon der richtige Platz für das Player-Objekt. Wenn du darauf von irgendwo anders zugreifen willst, mußt du es eben (per Referenz) beim Aufruf übergeben, z.B.:
void Item::use (Player& player) { player.irgend_eine_function(); }
-
Und das Item::use() wird in Inventory aufgerufen. Dann braucht auch Inventory das einzige game Objekt aus der main().
Ich mache das jetzt einfach mit einem globalen Objekt von Game.
Also in meinem ganzen Projekt existiert nur ein einziges globales objekt.
Das wird doch kein Problem sein?Weil damit ist alles viel einfacher, ich kann in der Item::use() einfach
game.xxx.... schreiben, und es ist immer das einzigartige game Objekt.Ich sehe da gar kein Problem
-
Hm, ich schon. Dein Design ist unnötig starr und unflexibel. Deine globale Variable mag jetzt problemlos funktionieren. Aber wenn du erweiterte Funktionalitäten brauchst, kommst du damit in Schwierigkeiten.
Wie gesagt, ich kenne jetzt dein Spieldesign nicht und weiß daher auch nicht, was für Anforderungen noch auf dich zukommen. Aber ich kann ja mal einfach raten:
Was ist, wenn du NPCs (non-player characters) einfügen willst? Die haben ja vielleicht auch ein Inventar. Und wohlmöglich können die auch Items anwenden (auf sich selbst oder auf den Player?). Spätestens ab diesem Moment bist du mit deinem globalen Player am Ende (zumindest, wenn du ihn auf die von dir vorgeschlagene Weise benutzt).
Andererseits, bist du offensichtlich eher noch Anfänger im Bereich OOP. Ich will dich jetzt auch nicht mit zuviel fortgeschrittenem Zeug verwirren. Wenn du umbedingt willst, verwendete halt eine globale Variable. Dein Computer wird deswegen nicht explodieren, soviel kann ich dir garantieren.
-
mit sowas muss jeder mal auf die nase fallen

gebranntes Kind scheut das Feuer :p
-
Was ist, wenn du NPCs (non-player characters) einfügen willst? Die haben ja vielleicht auch ein Inventar. Und wohlmöglich können die auch Items anwenden (auf sich selbst oder auf den Player?). Spätestens ab diesem Moment bist du mit deinem globalen Player am Ende (zumindest, wenn du ihn auf die von dir vorgeschlagene Weise benutzt).
Hmm, dann leite ich Player und NPC (und Gegner) von einer Basisklasse ab.
Die Klasse "Game" bekommt dann jeweils eine Instanz.
Ich habe ja keinen globalen Player, sondern eine globale Game-Klasse.Somit können Items zB. auf Player zugreifen:
game.getPlayer().addHealth(100);
Oder das Inventory braucht Daten:
game.getPlayer().getSlots();
oder oder oder...
Kannst du mir genau erläutern, wo ich ein Problem bekommen könnte?
Ja ich bin noch totaler Anfänger.
Wie sollte ich es denn ohne einem globalen Objekt von Game schaffen?
In meiner main() muss ich schon mal eines anlegen, damit ich init(), mainMenu() usw aufrufen kann.
Dann brauche ich noch an vielen anderen Stellen diese Instanz, habe sie aber nicht weil sie nicht global ist.
-
Wenn du deine Item::use Funktion automatisch immer den Player aus dem globalen Game-Objekt verwenden läßt, kannst du sie nicht für NPCs verwenden. Die use-Funktion sollte auf jeden Fall eine Referenz auf den Player übergeben bekommen (oder eventuell auf den NPC, da nimmt man aber dann stattdessen natürlich die Basisklasse). Ist doch auch logisch, oder? Wenn du einem Item sagst, daß es sich anwenden soll, dann mußt du ihm auch noch sagen, worauf es sich anwenden soll.
In meiner main() muss ich schon mal eines anlegen, damit ich init(), mainMenu() usw aufrufen kann.
Dann brauche ich noch an vielen anderen Stellen diese Instanz, habe sie aber nicht weil sie nicht global ist.Da eben liegt dein Problem. Du willst das Game-Objekt von jeder beliebigen Stelle aus verwenden können. Dafür wäre ein globales Objekt (oder viel besser noch ein Singleton) schon die richtige Lösung. Aber diese Forderung sieht für mich wie eine Schwäche im Design aus. Ich würde sie aufgeben. Ich würde sogar die Forderung aufgeben, daß du überhaupt auf das Game-Objekt zugreifen kannst (abgesehen von einer play-Methode vielleicht).
Verlagere alles in das Game-Objekt hinein. Dort hast du dann deine play-Methode, in der die Initialisierunug ausgeführt wird, wo Befehle vom User eingelesen und ausgeführt werden (ich hab dir dazu in einem anderen Thread schon mal ein Beispiel gegeben). Das ist die einzige saubere Lösuung, die mir dazu einfällt.
Somit können Items zB. auf Player zugreifen:
game.getPlayer().addHealth(100);
Wenn du den Player beim Funktionsaufruf übergibst, kannst du dir den ganzen Mist mit game.getPlayer() sparen (habe ich auch schon ein Beispiel zu gebracht).
Oder das Inventory braucht Daten:
game.getPlayer().getSlots();
Hier dieselbe Lösung. Du ruft die Methode von Inventory aus einer Methode von Game auf. Und da hast du Zugriff auf den Player, kannst ihn also (per Referenz) an die Methode von Inventory übergeben.
Nimm es mir nicht übel, aber ich glaube, du solltest noch mehr über den Umgang mit Klassen lernen, bevor du ernsthaft daran denken kannst OOP zu verwenden.
-
du solltest noch mehr über den Umgang mit Klassen lernen
Ich denke, du hast Recht

Danke trotzdem für deine Hilfen.