Auflistung von Instanzen
-
Suspekt, aber mit "meiner" Variante leicht zu vermeiden ;).
-
Ich möchte keinen neuen Thread anfangen, habe hier noch eine Frage.
Habe ich es so richtig gemacht?(Öffentliche Membervariablen vermeide ich jetzt total!)
//In der .h class Game { public: Game(); void init(); Player getPlayer(); private: Player player; }; extern Game game; //In der .cpp Player Game::getPlayer() { return player; }Und noch was:
Ich dachte, extern bedeutet, man kann eine Variable von einer .cpp in die andere "kopieren".
In meiner Header steht das extern aber auch, und somit habe ich von überall Zugriff (NUR meine Game-Klasse).Kann mir jemand "extern" genauer erklären?
-
Auch wenn ich den Rückgabetyp von getPlayer als "const Player&" efinieren würde, sieht das ganz gut aus.
Kann mir jemand "extern" genauer erklären?
"extern" erklärt dem Compiler, daß es zwar eine Variable des angegebenen Typs gibt - aber nicht hier. Das heißt, der Compiler stellt in der aktuellen Übersetzungseinheit keinen Speicher für diese Variable bereit, sondern hinterlässt nur eine Notiz "hier benötige ist ein "Game" Objekt mit dem Namen "game"" - der Linker geht dann später alle Libraries durch und findet dort (hoffentlich) diese Variable.
(das entspricht dem reinen Prototypen bei einer Funktion)
-
Wobei noch zu erwähnen ist, daß globale Variablen böse sind
Also, laß lieber die Finger davon!Falls du den Spieler von Außerhalb der Game-Klasse manipulieren willst, sollte der Rückgabetyp übrigens "Player&" lauten.
-
Nur die Game-Klasse soll auf die Player-Klasse zugreifen können.
So, zunächst ist es wichtig, dass getPlayer() immer dieselbe Instanz zurückgibt!
Also player soll immer player sein, und nicht plötzlich eine neue Instanz!
Das ist doch solange der Fall, solange die Game-Klasse existiert, oder?
(Weil ja in der Game-Klasse Player player; steht)
Oder habe ich da was falsch verstanden?Nun zum extern.
Bei mir steht im HEADER ein extern. Aber im Header brauche ich die Instanz gar nicht.1. Möglichkeit:
Game.h mit extern Game game;
Game.cpp mit globalem Game game;
Und dann kann ich von überall auf game zugreifen, was ich auch möchte.2. Möglichkeit:
Game.h ohne extern Game game;
Game.cpp mit globalem Game game;
Und dann zB. in der main.cpp ein extern Game game;Beide Möglichkeiten scheinen mir gleich, wo ist jedoch der Unterschied/Vorteil/Nachteil usw..
MfG
-
Beide Möglichkeiten sind schlecht, weil sie wie gesagt globale Variablen verwenden. Das deutet meist auf einen Design-Fehler hin.
Was die dieselbe Instanz von Player betrifft, mußt du darauf achten, daß du von getPlayer keine Kopie, sondern eine Referenz zurückgeben läßt (bei der Kopie würdest du halt jedesmal einen neuen Player bekommen). Darum war deine ursprüngliche getPlayer Funktioni vermutlich nicht das, was du haben willst.
-
Danke, kannst du mir getPlayer() entsprechend umschreiben?
Ich bin gerade erst beim Kapitel Referenzen und Zeiger angekommen, habe mir noch nichts angeschaut.
So, also ich soll keine global definierte Instanzen verwenden?
Das heißt, ich lasse extern Game game; weg, und erstelle nur dort eine Instanz, wo ich sie benötige? (zB. in der main() Funktion)Bin für weitere Tipps dankbar

-
ceplusplus schrieb:
Danke, kannst du mir getPlayer() entsprechend umschreiben?
Ganz einfach - du mußt nur den Rückgabetyp der Methode von "Player" auf "Player&" (wenn der Aufrufende das Objekt ändern darf) bzw. "const Player&" (wenn er das Objekt nicht ändern darf) verändern.
So, also ich soll keine global definierte Instanzen verwenden?
Das heißt, ich lasse extern Game game; weg, und erstelle nur dort eine Instanz, wo ich sie benötige? (zB. in der main() Funktion)Ja - allerdings hat dann jede Instanz von Game ihr eigenes Player-Objekt.
(btw, eventuell könntest du auch mal nach "Singleton" googlen)
-
Die Funktion muß heißen:
Player& getPlayer()Die Implementierung kann so bleiben, d.h.:
Player& Game::getPlayer() { return player; }Zur Game-Klasse: Ja, du kannst zum Beispiel eine Instanz in der main Funktion anlegen. Das könnte zum Beispiel so aussehen:
int main() { Game theGame; theGame.play(); }Wesentlich mehr sollte in der main-Funktion ohnehin nicht drin stehen.
Dein ganzes Spiel kommt dann in Game::play hinein (beziehungsweise in davon aufgerufene Funktionen). Und da du in Game::play direkten Zugriff auf alles hast, was zu Game gehört (z.B. player), kannst du dir die getPlayer-Funktion dann gleich komplett sparen (ist nur ein Vorschlag, da gibt es sicher mehr als einen Weg das vernünftig zu designen).
-
Okay danke für die vielen Antworten und Hilfen!
(Singletons schaue ich mir lieber erst an, wenn ich mit meinem Buch fertig bin)
//EDIT:
Eins noch:
getPlayer() Kann ich ja nicht weglassen, wie soll ich sonst zugreifen?Zum Beispiel:
game.player.getName();
Geht dann nicht:
error C2248: "player" : Kein Zugriff auf private Element, dessen Deklaration in der Klasse "Game" erfolgte
-
Wenn du player.getName() von einer Funktion aus aufrufst, die eine Methode von Game ist, geht das sehr wohl.
Wenn du player.getName() von einer Funktion A aus aufrufst, die keine Methode von Game ist, sollte A zumindestens von einer Funktion aus aufgerufen werden, die eine Methode von Game ist (ich hoffe ich mache das jetzt nicht zu kompliziert für dich). In dem Fall kannst du beim Aufruf von A einfach eine Refenrenz auf Player übergeben.
Singleton hätte ich dir wohlmöglich auch vorgeschlagen, aber ich hatte noch deine anderen Posts im Hinterkopf, und das sieht mir zumindest auf den ersten Blick so aus als könntest du soweit erst mal ohne das Singleton Pattern auskommen (kann natürlich auch sein, daß ich mich da irre; hab ja schließlich nur Ausschnitte deines Entwurfs gesehen).
-
Das Problem dabei ist nur:
Wenn die Klasse "Player" mehr als 20 Methoden hat, dann müsste ich in die Klasse "Game" auch alle diese Methoden schreiben. Das würde ich mir gerne ersparen und es macht den Code vermutlich auch nicht besser...
-
Hm, offenbar habe ich mich doch zu kompliziert ausgedrückt. Natürlich mußt du die Methoden von Player nicht nach Game kopieren.
Ich versuch mal mir ein Beispiel für eine Game-Klasse aus den Fingern zu saugen (Code ungetestet).
// Game.h #include "Player.h" class Game { Player d_player; bool d_running; void createPlayer(); char getCommand(); void executeCommand (char c); public: Game(); void play(); };// Game.cpp void Game::createPlayer() { // Namen einlesen, usw. } char Game::getCommand() { // Optionen ausgeben und von cin einen Befehl einlesen } void Game::executeCommand (char c) { // Befehl ausführen // an dieser Stelle kann zum Beispiel soetwas stehen wie d_player.getName(); } Game::Game() { // verschiedenes Zeugs } Game::play() { createPlayer(); while (d_running) { char c = getCommand(); executeCommand (c); } }Edit: Rechtschreibung
Edit: Noch mal Rechtschreibung, bah!
Edit: Groß- und Kleinschreibung! Hilfe!
-
Ich muss mich näher mit Klassen beschäftigen...
Jedenfalls ist es mir im Moment lieber, game.getPlayer(). zu verwenden.