Strukturierung eines Projekts (die eigentliche Fortsetzung..)
-
Hallo zusammen,
erstmal vielen herzlichen Dank für die Ratschläge, rapso. Ich glaube im Nachhinein
eine verwaltungsklasse hat keine member von irgendwelchen objekten, lediglich einen kontainer in dem die verwalteten resourcen sind.
das war genau das, was ich gebraucht habe!
Und nach dem Ansatz, wie ein möglicher Container aussehen könnte, habe ich mich dann erstmal auf die Suche nach Informationen begeben, denn leider beherrsche ich C++/STL Container nicht. ...noch nicht
Hm, leider verbleiben doch einige Fragen... ich stelle sie jetzt einfach mal hier, auch wenn das Ganze erstmal eher nicht in dieses Forum gehört..?!
Ich verstehe nicht ganz, wo denn nun mein Objekt der Klasse Mesh definiert wird. Könnte es in etwa so laufen?
void ResourcenManager::insertMesh(m_MeshResources) { //also entweder so?! m_MeshResources.insert(pair<tdMeshName,tdMeshResource>, "tiger.x", tdMeshResource mesh); //oder so?! m_MeshResources["tiger.x"] = tdMeshResource mesh; return; }Diese Methode würde ich dann bei der Initialisierung der Anwendung aufrufen. Allerdings müsste ich doch, wenn ich das auf diese Weise mache, noch einen Zeiger (mesh) vom Typ tdMeshResource in der Headerdatei deklarieren...?!
Eine andere Frage, die eigentlich nebensächlich ist, hat sich mir beim studieren der Standardcontainer gestellt. Stroustrup sagt
Elemente, die sich in einem Container befinden, sind Kopien der eingefügten Objekte.
Ist das nicht irgendwie Speicherplatzverschwendung?? Was daran verstehe ich falsch?

Soweit erstmal von mir.
Ps.: Hier (http://www.c-plusplus.net/forum/viewtopic-var-t-is-182150.html) der Link zum ersten Thread und nochmal vielen Dank für die Hilfe!
-
Hi,
m_MeshResources.insert(pair<tdMeshName,tdMeshResource>("tiger.x", mesh)); // und m_MeshResources["tiger.x"] = mesh;sind beide richtig.
Ja, es werden tatsächlich Kopien der Objekte gespeichert und ja, das ist Overhead. Aber deswegen speichert man auch nicht die Objekte selbst im Container, sondern irgendetwas, das auf das eigentliche Objekt verweise (das Objekt existiert dann nämlich trotzdem nur einmal). Beispielsweise einen (smart-)pointer.
-
Ja gut,
aber wie speicherst du dann die echten Objekte?
Ich mein, irgendwo müssen die doch auch in einem Feld/Container stecken.Dann kann man doch auch gleich die gleichartigen Objekte (also immer Texturen, Modelle usw. getrennt) in ein Feld packen und dann immer die Adresse zurückgeben, in etwa so:
textur* TexturVerwalter::holeTextur(string suchName) { textur *t; int c = 0; //texturContainer ist ein std::vector oder so, der die geladenen Texturen speichert for(t = texturContainer[0]; c < texturContainer.size();c++, t++) { if(t->name == suchName) return t; } return NULL; }
-
da das ganze bei dir wohl auf ein spiel hinausläuft einige beispiele.
du hast ein spiel programmiert das heisst wie? hm... nehmen wir einfach ma starcraft 2:
class Unit { public: void TOETEN(Unit *target); private: std::string m_name; };//Ja in Starcraft 2 wird das genauso gemacht!!11111111111 class UnitManager { public: //... void addUnit(Unit *u) { m_units.push_back(u); }; private: std::vector<Unit*> m_units; };es gibt situationen, da ist es durchaus nötig nebem dem eigentlichen zeiger, welchen man übergibt noch einen weiteren im "hauptprogramm" zu haben, da man eine einheit ja nicht nur innerhalb der verwaltungsklasse ansprechen möchte, sondern auch vom hauptprogramm aus.
class MyGame { public: void hauptprogrammschleife() { //... Unit *meinzergling = new Unit(); Unit *gegnerseinzergling = new Unit(); m_unitmanager.addUnit(meinzergling); m_unitmanager.addUnit(gegnersenizergling); //... } private: UnitManager m_unitmanager; }du hast immernoch die möglichkeit, ausserhalb der verwaltungsklasse bzw ohne umständliches zurechtfummeln eines guten [] operators die möglichkeit, auf die objekte zuzugreifen.
//... void hauptprogrammschleife() { //... if(spieler hat auf gegnerische unit geklickt && spieler hat meinzergling angewählt) meinzergling->TOETEN(gegnerseinzergling); //... }Hierbei wäre es recht umständlich jedes mal die zerglinge per getZergling() (oder so) aus der verwaltugnsklasse zu holen.
Es gibt aber auch genügend Beispiele die aufzeigen, dass man nicht unbedingt einen "hauptprogramminternen" zeiger auf das objekt braucht.
void hauptprogrammschleife() { //... m_guiverwaltungsklasse.addButton(new Button(800,600,funktionszeiger)); //... }Die Verwaltungsklasse hat den einzigen Zeiger auf das neue Objekt. Die Verwaltungsklasse kümmert sich später übrigens auch um das reinigen des Speichers.
Der Code oben ist natürlich in keinster Weise so genau, wie man es später umsetzen wird, aber eine Idee sollte es dir trotzdem verschaffen.
mfg TravisG