c++ Objekte indizieren. wie?
-
Hallo,
da ich neu hier bin erstmal ein hallo an alle!
Ich habe ein Problem bei dem mir hoffentlich der eine oder andere weiterhelfen kann. Ich hoffe ich schaffe es, mich verständlich auszudrücken...Ich möchte ein ganz kleines mud programmieren und habe mir eine Klasse player ausgedacht mit diversen Attributen (Stärke, Mut, etc..) und Methoden (schau, nimm, gehe etc.)
Bei einem Player hab ich kein Problem, da ich für den ersten angenommenen Socket mir dann das eine Player - Objekt instantiiere...
Sobald ich aber serverseitig mehrere Leute akzeptieren möchte, wird es schwer, da ich absolut keine Idee habe wie ich das handlen soll.
Ich dachte an sowas wie ein Array von Objekten, wo ich bei jedem Update (heartbeat) einfach mit einer Schleife von 1-AnzahlPlayer durchlaufe und die Updates über die jeweiligen Sockets raus sende. Klappt aber nicht, da Klassen anscheinend nicht als Arrays funktionieren.
Ich habe mir schon vorhandene Sourcecodes von Muds angeschaut, die sind aber teilweise gar nicht oder für mich unverständlich dokumentiert....
Meine Frage lautet also:
Wie kann man eine Riesenmenge von Objekten (von verschiedenen Klassen) indizieren (also mit Idexen versehen) und gezielt ansprechen?
Hat jemand ein leicht verständliche Lösung oder ein leicht verständlichen Tutorial an der Hand, welches idealerweise auch noch auf deutsch ist?
Gruss
RobinPS: ide ist MinGW Developer Studio mitsamt dem mitggeliefertem Compiler unter Windows32
-
Klappt aber nicht, da Klassen anscheinend nicht als Arrays funktionieren.Also diesen Satz verstehe ich nicht. Wie hast du es denn versucht? Ichkann mir vorstellen was du machen willst, deshalb hier mal ein Lösungsansatz. Gehen wir davon aus, deine Klasse heißt Player und du willst eine beliebige Anzahl an Playern halten und durchlaufen. Da gibt es in der C++ Standard-Library gute Lösungen.
So kannst du schon mal ein flexibles Array verwalten (das macht vector für dich):
std::vector<Player> players; Player p("Player 1"); // als Beispiel hat der Playerkonstruktor einen Namensparameter players.push_back(p); // ...So, wie kann man diesen vector komplett durchlaufen?
std::for_each(players.begin(), players.end(), funct);funct ist dabei eine Funktion die die Player behandelt:
void funct(Player &p) { // hier was mit dem Player machen. }Du kannst aber natürlich auch per Index drauf zugreifen:
players.at(i); // i ist der Index. players[i]; // geht auch ohne Problem players.size(); // gibt die Größe eines vectors zurückBesorg dir mal ein vernünftiges Buch über die C++ Standardbibliothek, z.B. das von Kuhlins und Schrader aus dem Springer Verlag. Das sind alles Basics die man können muß!
-
Warum sollte es mit einem Array nicht funktionieren ?
Angenommen die Klasse für einen Spieler heisst "Player"int AnzahlMaxSpieler =255; Player Players[AnzahlMaxSpieler];Aber mit einem Array ist das sehr Unflexibel, wenn es dir nicht reicht kannst du auch eine Liste benutzten/machen.
-
Vielen Dank für die Hinweise.
Hatte ich vergessen zu erwähnen, dass ich von Delphi nach C++ migriere, und dieses kleine Projekt sozusagen mein eigenes Tutorial ist?Na jedenfalls werde ich mir mal die enpfohlene Literatur beschaffen und mich solage im Internet über Vektoren Schlau machen.
Zu den Klassen als array - ich weiss die Fehlermeldung nicht mehr auswendig, war sowas wie "error:bad array initializer" oder sowas.
Statische Arrays sind hier sowieso eher ungünstig, sodass ich dann auf die Vektoren ausweichen werden.Gruss
R
-
LJ_1102 schrieb:
Warum sollte es mit einem Array nicht funktionieren ?
Angenommen die Klasse für einen Spieler heisst "Player"int AnzahlMaxSpieler =255; Player Players[AnzahlMaxSpieler];Aber mit einem Array ist das sehr Unflexibel, wenn es dir nicht reicht kannst du auch eine Liste benutzten/machen.
Geht aber nur für Klassen mit parameterlosem Konstruktor.
Bye, TGGC (Fakten)
-
Hallo,
ich habe jetzt folgende böse Fehlermeldung...
Compiling source file(s)... main.cpp C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\vector.tcc: In member function ` player& player::operator=(const player&)': C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\vector.tcc:230: instantiated from `void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<_Tp*, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = player, _Alloc = std::allocator<player>]' C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\stl_vector.h:603: instantiated from `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = player, _Alloc = std::allocator<player>]' main.cpp:22: instantiated from here C:\MinGWStudio\MinGW\include\c++\3.3.1\bits\vector.tcc:230: error: non-static const member `const long unsigned int player::id', can't use default assignment operator MyServerApp.exe - 4 error(s), 0 warning(s)Auszug aus der Klassendefinition player:
class player { public: const unsigned long id; [...] // definition of ctor player (unsigned long nnn):id(nnn){};Und nur 3 Zeilen in der main :
std::vector<player> players; player p(1); players.push_back(p);Wenn ich die letzte Zeile aus main auskommentiere, läufts ohne errors durch, nur der push_back verursacht die obige Fehlermeldung...
Was mache ich falsch?Gruss
R
-
Container erwarten, daß ihre Elemente kopierbar sind - und das klappt nicht, wenn Player::id konstant ist (entweder du verzichtest auf das const oder du schreibst einen eigenen operator= für deine Klasse).
-
Mach die ID doch private und nicht const!!! Dann keine setter-Methode, es reicht doch eine getter. Die ID ist private und kann von niemandem mehr geändert werden. So wie du das machst (Membervariablen public), macht das wohl niemand.
class player { private: // !!! unsigned long id; [...] public: // definition of ctor player (unsigned long nnn):id(nnn){}; // kann von außen nur noch gelesen nicht geändert werden unsigned long getId() const { return id; } }
-
Hallo nochmal,
ich hab mir eure Tips zu Herzen genommen, und es scheint alles soweit zu funktionieren.
Nun hab ich noch eine Frage zu den Vektor-Objekten...
Wenn ich mit .erase das Objekt lösche auf das der Iterator gerade zeigt, wird dann der Speicher den das Objekt belegte dann automatisch freigegeben?Irgendwie feht mir hier 'new' und 'delete' bei den Vektoren.....
Gruss
R
-
Wo kein new, da auch kein delete.
Wenn du keine Pointer im Vector hast, brauchst du dich auch nicht um das löschen kümmmern.Vielleicht hilft dir das hier zum besseren Verständnis weiter:
http://www.kharchi.de/cppratgeber1.htm