Klassen und Arrays
-
Danke
-
Wenn sowieso nur eine Spielfeldgrösse existiert und diese auch zur Compilezeit bekannt ist, braucht man den Umweg über Templates (von denen ich vermute, dass sie der Threadersteller noch nicht kennt) nicht zu gehen.
const-Variablen reichen dafür aus.class Feld { static const int Laenge = 35; static const int Breite = 20; int Array[Laenge][Breite]; };
-
Die Größe von statischen Arrays muss zur Compilezeit feststehen. Tut sie dass nicht, musst du mit dynamischen Strukturen arbeiten (d.h. new und delete benutzen). Wenn ich mir aber dein Programm so angucke, vermute ich mal, dass dein Spielfeld immer gleich groß sein soll und du einfach nicht weißt, wie man in C++ Konstanten und statische Member benutzt. In letzterem Fall könntest du dann folgendes machen:
class CFeld { private: static const int x=15; static const int y=10; int Array[x][y]; };
-
wx++ schrieb:
Entweder legst du das Array dynamisch an oder nimmst ein Klassen-Template:
template<int XSIZE, int YSIZE> class CFeld { int Array[XSIZE][YSIZE]; }muss man da was mit std::allocator mache?
-
template n00b schrieb:
muss man da was mit std::allocator mache?
Nein (aber man könnte natürlich). Wie kommst du darauf?
-
weil mich interessiert, wie das geht.
evtl. will ich mal eine kleine 3d bitmap bibliothek anfangen zu programmieren.mit meinem jetztigen kenntnisstand hätte ich es so gemacht:
class CFeld { private: int* Array; unsigned x, y; void ChkXY ( unsigned x, unsigned y ){ if ( x > this->x || y > this->y ) cout << endl << "Touch too much!" << endl; assert ( x < this->x && y < this->y ); } public: CFeld( unsigned x, unsigned y ); int GetValue( unsigned x, unsigned y ); void SetValue ( unsigned x, unsigned y, int value ); }; CFeld::CFeld ( unsigned x, unsigned y ) { this->x = x; this->y = y; Array = new int [x*y]; for ( unsigned i = 0; i < x*y; i++ ) Array[i] = 0; } void CFeld::SetValue ( unsigned x, unsigned y, int value ) { ChkXY ( x, y ); Array[y*this->x+x] = value; } int CFeld::GetValue ( unsigned x, unsigned y ) { ChkXY ( x, y ); return Array[y*this->x+x]; } int main() { CFeld cfeld ( 8, 8 ); cfeld.SetValue( 4, 6, 99 ); cout << cfeld.GetValue ( 4, 6 ); cout << cfeld.GetValue ( 666, 999 ); return 0; }nu dacht ich wäre vllt. besser, sprachmittel von c++ zu kennen, die das irgendwie ... hmm ... einfacher machen?
-
template n00b schrieb:
nu dacht ich wäre vllt. besser, sprachmittel von c++ zu kennen, die das irgendwie ... hmm ... einfacher machen?
Definitiv. Ein sehr essentieller Bestandteil der C++-Standardbibliothek ist die Standard Template Library (STL). Diese bietet Container und Algorithmen an, welche dir mühsame Dinge wie manuelle Speicherverwaltung abnehmen, ein sehr komfortables Interface anbieten und dir erlauben, zu abstrahieren und dich auf die wirklich wichtigen Dinge zu konzentrieren.
Als Einführung kann ich dir diesen Artikel des C++-Forenmagazins empfehlen. Auch Teil 2 und 3 sowie andere Artikel (z.B. über Templates, Zeiger) solltest du dir unbedingt genauer unter die Lupe nehmen.
P.S.: Mit deiner jetzigen Klasse hast du ein Memory Leak, da du den von
newangeforderten Speicher nicht freigibst. Ausserdem kommt es zu Problemen, wenn Instanzen kopiert oder zugewiesen werden, da diese dann auf den gleichen Speicher verweisen. Zwei weitere Fehler, die durch die Verwendung der STL stark eingeschränkt werden können.
-
Nexus schrieb:
P.S.: Mit deiner jetzigen Klasse hast du ein Memory Leak, da du den von new angeforderten Speicher nicht freigibst. Ausserdem kommt es zu Problemen, wenn Instanzen kopiert oder zugewiesen werden, da diese dann auf den gleichen Speicher verweisen. Zwei weitere Fehler, die durch die Verwendung der STL stark eingeschränkt werden können.
stimmt, hätte wenigstens den destruktor noch mit reinbauen sollen
CFeld::~CFeld() { delete [] Array; }zuweisungsoperator und kopierkonstruktor würde ich auch noch hinbekommen, aber wie würde ich da mit templates rangehen: gibt es da was fertiges oder müsste ich das selber schreiben?
-
CFeld__~CFeld() schrieb:
zuweisungsoperator und kopierkonstruktor würde ich auch noch hinbekommen, aber wie würde ich da mit templates rangehen: gibt es da was fertiges oder müsste ich das selber schreiben?
Wenn du selbstverwaltende Objekte als Member hast - also keine rohen besitzenden Zeiger, sondern z.B. Container - brauchst du weder Destruktor, noch Kopierkonstruktor, noch Zuweisungsoperator selbst zu implementieren. Die compilergenerierten Funktionen reichen da völlig aus.
-
Nexus schrieb:
CFeld__~CFeld() schrieb:
zuweisungsoperator und kopierkonstruktor würde ich auch noch hinbekommen, aber wie würde ich da mit templates rangehen: gibt es da was fertiges oder müsste ich das selber schreiben?
Wenn du selbstverwaltende Objekte als Member hast - also keine rohen besitzenden Zeiger, sondern z.B. Container - brauchst du weder Destruktor, noch Kopierkonstruktor, noch Zuweisungsoperator selbst zu implementieren. Die compilergenerierten Funktionen reichen da völlig aus.
Es gibt eine Ausnahme: wenn starke Exceptionsicherheit benötigt wird und die Zuweisung eines Members (außer des Ersten bzw. der ersten Basisklasse) eine Exception werfen kann. Dann muss der Zuweisungsoperator trotzdem selbst definiert werden.
Die Standardcontainer bieten selbst nur die schwache Garantie.
-
Nexus schrieb:
Wenn du selbstverwaltende Objekte als Member hast - also keine rohen besitzenden Zeiger, sondern z.B. Container - brauchst du weder Destruktor, noch Kopierkonstruktor, noch Zuweisungsoperator selbst zu implementieren. Die compilergenerierten Funktionen reichen da völlig aus.
ja, das ist mir bekannt :). bleibt für mich noch die frage ungeklärt, ob es zum erzeugen von 2d/3d koordinaten-arrays fertige c++ klassen gibt.
was ist mit dem vorschlag von wx++:wx++ schrieb:
Entweder legst du das Array dynamisch an oder nimmst ein Klassen-Template:
template<int XSIZE, int YSIZE> class CFeld { int Array[XSIZE][YSIZE]; }wäre das eine vereinfachung gegenüber meinem ansatz?
-
-