Dynamisches Erzeugen von Objekten in der OOP durch Variable???
-
Hi,
haben Hausaufgaben aufebekommen unsere Klasse (reale Schulklasse hehe) als C++ Klasse in OOP zu amchen.
Nun habe ich einige Unterprogramme inkl. Menüführung durch switch-case gemacht. Im Menü ist der Punkt: "Schüler erstellen". Nun will ich die Anzahl abfragen und durch eine dynamische Erzeugung des Objektes erstellen.
Der Compiler meckert aber weil er eine Konstante erwartet.
Kann ich das Problem übergehen oder muss ich die Art der Mnüführung in soweit ändern, dass ich einen Schüler nach dem anderen erstellen lassen muss und der Benutzer nun nur noch entscheiden kann ob er einen weiteren erstellen will oder nicht (do-Schleife) ???Unterfunktion zum schreiben von Schuelern
void schErzeugen(void) { int anzahl=0; cout << "Bitte Anzahl der zu erstellenden Schueler eingeben: "; cin >> anzahl; ITA2C *Schueler[anzahl]; cout << "Taste druecken um ins Hauptmenue zurueck zu kommen"; getch(); clrscr(); menu(); }Auszug aus der Klasse ITA2C
class ITA2C { private: string name; string vorname; int note_prg; int note_mathe; int fehlstunden;
-
Kovu schrieb:
Der Compiler meckert aber weil er eine Konstante erwartet.
Deswegen musst du hier manuell Speicher reservieren. Dies kannst du von Hand erledigen:
int main() { size_t x; cin >> x; size_t* dyn_arr = new size_t[x]; // hier muss x nicht zur compile-Zeit bekannt sein. // mach was mit dyn_arr. delete[] dyn_arr; // nicht vergessen, den Speicher wieder freizugeben. }Google diesbezüglich eventuell nach new/new[] und delete/delete[] für mehr Infos.
Ansonsten kannst du auch std::vector verwenden, einen Kontainer aus der STL. Mit ihm arbeitest du wie mit einem "normalen" Array, nur das er den Speicher selbstverwaltet, sprich, du musst dich nicht darum kümmern wie viele Elemente dein std::vector aufnehmen muss, etc.
Gruß Caipi
-
Sry aber mein OOP ist noch nciht so gut das ich das sofort verstehe.
Also size_t is deine Klasse und X dein Objekt oder?
Wie kannst du den dann aber ein Objekt einlesen?Bin voll verwirrt -.-*
Bitte mal ne genau Erklärung was was ist oder am besten meine Klasse verwenden, so kann ich das nachvollziehen was du tust. Sorry!!!
-
Kovu schrieb:
Also size_t is deine Klasse und X dein Objekt oder?
size_t ist ein Typ (meistens ein typdef auf unsigned long/int), welcher große ganzahlige, positive Werte aufnehmen kann.
Wie kannst du den dann aber ein Objekt einlesen?
size_t ist meistens kein Objekt. Man kann aber ein Objekt einlesen, wenn man die I/O-Operatoren für selbiges überlädt :).
Bitte mal ne genau Erklärung was was ist oder am besten meine Klasse verwenden, so kann ich das nachvollziehen was du tust. Sorry!!!
int main() { unsigned int x; cin >> x; ITA2C* dyn_arr = new ITA2C[x]; // sizeof(x * Objekte) Byte Speicher reservieren und den Ctor von jedem Objekt ITA2C aufrufen. // mach was mit dyn_arr. delete[] dyn_arr; // nicht vergessen, den Speicher wieder freizugeben. }Gruß Caipi
-
ich habs grad mal gemacht mit arrays
#include <string> #include <iostream> using namespace std; class Student // Schülerklasse { string name; bool idiot; }; int main() // int!!! main() { int numStudents = 0; // Anzahl Schüler Student *students = NULL; // Zeiger auf Schülerarray cout << "Wie viele Schüler haben wir denn? " << flush; // Ausgabe cin >> numStudents; // Eingabe students = new Student[numStudents]; // Ausreichend Speicher für Schülerarray anfordern und Zeiger darauf setzen /* mach was */ delete[] students; // Aufräumen return 0; // Windows sagen, dass das Programm ohne Probleme beendet wurde }Aber du solltest dir auf jeden Fall mal Vektoren aus der STL anschauen. Sind viel handlicher.
-
Cool, wieder was gelernt ^^ Danke.
Student *students = NULL; students = new Student[numStudents];auch zusammenfassbar in
Student *students = new Student[numStudents];???
Und
unsigned int x;gleich wie
size_t x;???
Und jetzt noch die wahrscheinlich meistgehasste Frage jeden Programmierers: Warum?
Warum klappt es bei mir nciht und warum bei euch? Was hat das mit Zeiger auf sich? (Möchte es gerne klipp und klar verstehen, weil es mir später sonst nichts bringt, ok?)
danke nochmal
-
xindon schrieb:
int main() // int!!! main()
Hat irgend wer was verbrochen?int numStudents = 0; // Anzahl Schüler Student *students = NULL; // Zeiger auf SchülerarrayIn C++ gibt es neuerdings ein Feauture, das es erlaubt Variablen "auch mal" nicht am Anfang einer Funktion zu deklarieren.

cout << "Wie viele Schüler haben wir denn? " << flush; // Ausgabe cin >> numStudents; // EingabeDas flush ist hier unötig, da automatisch beim Wechsel zwischen Input und Output-Streams der Puffer geflushed wird.
Kovu schrieb:
Student *students = NULL; students = new Student[numStudents];auch zusammenfassbar in
Student *students = new Student[numStudents];Jup. Ist Imho sogar schöner.
unsigned int x;gleich wie
size_t x;Muss afaik nicht zwangsläufig so sein (oder?). Siehe eventuell in stddeff.h nach dem korrekten Typ. (Es schadet allerdings nichts, wenn du davon ausgehst, dass size_t soetwas wie unsigned int ist :)).
Warum klappt es bei mir nciht und warum bei euch? Was hat das mit Zeiger auf sich? (Möchte es gerne klipp und klar verstehen, weil es mir später sonst nichts bringt, ok?)
Was klappt bei dir nicht? Desweiteren empfehle ich dir in einem Buch deiner Wahl noch mal dynamische Speicherverwaltung uvam durchzulesen :).
Gruß Caipi
-
Kovu schrieb:
Student *students = NULL; students = new Student[numStudents];auch zusammenfassbar in
Student *students = new Student[numStudents];Ich mags halt lieber oben schön mit null initialisiert

----
Kovu schrieb:
Warum klappt es bei mir nciht und warum bei euch?
ITA2C *Schueler[anzahl];Ich hab keine Ahnung, was das sein soll. Vielleicht en Zeigerarray oder sowas *g*.
Du fordest dort ja gar keinen neuen Speicher an.
Das musst du mit new machen, weil zur Compilezeit unbekannt ist, wie viel Speicher das Programm benötigen wird.
Den angeforderten Speicher solltest/musst du am Ende wieder mit delete freigeben.In meinem Code habe ich es ja extra kommentiert:
Es wird passend Speicher angefordert und der Zeiger wird darauf gesetzt.
Jetzt kannst du den Zeiger benutzen, um auf das Array zuzugreifen, weil du jetzt weißt, wo es steht, nachdem es erstellt wurde.Kovu schrieb:
Cool, wieder was gelernt ^^ Danke.
Jap, das ist cool
und vorallem sehr wichtig. Gut so :>-----
cout << "Wie viele Schüler haben wir denn? " << flush; // Ausgabe cin >> numStudents; // EingabeDas flush ist hier unötig, da automatisch beim Wechsel zwischen Input und Output-Streams der Puffer geflushed wird.
Boa du, das sind doch so Kleinigkeiten *g*. So gravierend ist ein flush bestimmt nicht :>
-------
In C++ gibt es neuerdings ein Feauture, das es erlaubt Variablen "auch mal" nicht am Anfang einer Funktion zu deklarieren.

In größen Projekten mach ich das auch so. Nur in so kleinen Dingern find iche es einfach übersichtlicher, weil man weiß, was für Variablen benutzt werden.
-------
Caipi schrieb:
xindon schrieb:
int main() // int!!! main()
Hat irgend wer was verbrochen?Es gibt doch fast jeden Tag 3 Threads wo ein Anfänger void main() benutzt...
-
void main? das ist lol ^^
Naja gut.
Bedanke für an alle und proge fein weiter...
das nächste Prob kommt bestimmt. Alles Gute ^^