Neue Objekte zur Laufzeit anlegen und später wieder auflisten
-
Hi,
ich habe folgendes Problem:
Ich möchte meiner Bewerbung ein kleines Projekt beilegen. Dort kann der User eine Reihe von Personen (Vorname, Nachname, Alter, Größe und Gewicht) angeben. Diese werden werden zu Objekten der Klasse Personen.
Außerdem soll der User die Möglichkeit haben alle angegebenen Personen ausgeben zu lassen. Doch wie greife ich auf Objekte zu, deren Name mir nicht bekannt ist?Wäre über eine schnelle Antwort unendlich dankbar.
MfG
RapistseinHobby
-
Na ich würde mir eine Klasse erstellen also CPerson zum Beispiel, darin befindet sich alles was zu der jeweiligen Person gehört, die wird bei jeder eingabe mit new neu erstellt und den Zeiger auf die Klasse legst du in einer CPtrList ab. Beim Anzeigen brauchst du nur duch die liste zu gehenm, ich weiss nicht was dir dabei bekannt sein muß. wenn du das in der Liste hast, kannst du dir dann noch gedanken machen zwegs Serialisierung zum Beispiel um das in einer Datei zu speichern oder daras wieder zu laden oder entsprechende Suchfunktionen zu intergieren.
-
Danke für deine Antwort. Leider kann ich mit dem Begriff CPtrList nichts anfangen.
Ich habe das Problem einfach mit einem Pointer-Array gelöst.
Personen *p[255]Personen *personHinzufuegen();
Diese Funktion fragt die Informationen über die Person ab und ruft den Konstruktor auf, um das neue Objekt zu erstellen. Zuletzt gibt sie die Adresse des Objekts zurück und speichert sie in *p[n], damit ich mit der Adresse auch von der Mainfunktion aus arbeiten kann. Z.B um die Personen aufzulisten oder welche zu entfernen.Hier mal mein Quelltext:
/* main.cpp */ #include "Person.h" #include <iostream> #include <string> using namespace std; void personenAuflisten(Person *p){ p->ausgabe(); } void personEntfernen(){ } Person *personHinzufuegen(){ string vorname, nachname; int alter; float groesse, gewicht; cout << "Bitte geben Sie den Vornamen ein!" << endl; cin >> vorname; cin.ignore(); cout << "Bitte geben Sie den Nachnamen ein!" << endl; cin >> nachname; cin.ignore(); do{ cout << "Bitte geben Sie das Alter ein!" << endl; cin >> alter; cin.ignore(); }while(alter<=0); do{ cout << "Bitte geben Sie die Groesse (in m) ein!" << endl; cin >> groesse; cin.ignore(); }while(groesse<=0.0); do{ cout << "Bitte geben Sie das Gewicht (in Kg) ein!" << endl; cin >> gewicht; cin.ignore(); }while(gewicht<=0.0); return(new Person(vorname, nachname, alter, groesse, gewicht)); } void main(void){ Person *p[255]; int antwort, i, j=0; do{ //Auswahlmenü zu welchem der User immer wieder gelangt, bis er das Programm beenden //möchte (Auswahl 4) cout << "1. Person hinzufuegen" << endl; cout << "2. Person entfernen" << endl; cout << "3. Personen auflisten" << endl; cout << "4. Programm beenden" << endl; cin >> antwort; cin.ignore(); //Ignoriert die Eingabetaste, welche auch als Eingabe gesehen wird switch(antwort){ case 1: p[j] = personHinzufuegen(); j++; break; case 2: personEntfernen(); break; case 3: for(i=0; i<=(j-1); i++){ personenAuflisten(p[i]); cout << endl; } system("pause"); break; case 4: break; default: //Bei einer falschen eingabe wird der User informiert. //Falsch sind alle Eingaben, außer 1,2,3 und 4. cout << "Falsche Eingabe!" << endl; } system("cls"); }while(antwort!=4); }
/* Personen.h */ #pragma once #include <string> class Person{ private: std::string vorname; std::string nachname; int alter; float groesse; float gewicht; float bmi; public: void ausgabe(); Person(std::string vorn, std::string nachn, int alt, float gr, float gew); ~Person(void); };
/* Personen.cpp */ #include "Person.h" #include <iostream> using namespace std; void Person::ausgabe(){ cout << "Vorname: " << this->vorname << endl; cout << "Nachname: " << this->nachname << endl; cout << "Alter: " << this->alter << endl; cout << "Groeße: " << this->groesse << endl; cout << "Gewicht: " << this->gewicht << endl; cout << "BMI: " << this->bmi << endl; } Person::Person(std::string vorn, std::string nachn, int alt, float gr, float gew) :vorname(vorn), nachname(nachn), alter(alt), groesse(gr), gewicht(gew), bmi(gew/(gr*gr)) { } Person::~Person(void){ }
-
na das ist klar weil du auch C++ in der Console benutzt und hier es eigentlich um MFC geht, deswegen kannst du nix mit anfangen.
Die Lösung über ein Pointer-Array geht auch, ist aber sehr unsicher, zumindest würde ich entweder eine Container-Klasse wie std::verctor verwenden oder zumindest das Array am anfang mit 0 Initialisieren. Denn mit deinen zähler j wirst du sicher probleme bekommen wenn du eine person aus der mitte deiner Arraybelegung löschen willst, belegst du aber unbenutzte stellen immer nit NULL, kannst du die bei der ausgabe überspringen und gibst immer alle 255 aus, was zumindest keine Abstürze verursacht. Sollten nach dem löschen wieder ein neuer Eintrag hinzukommen, kannst du den ersten leeren Eintrag suchen.
-
Also sowas würde ich meiner Bewerbung nicht beilegen
-
kommt doch drauf an was der grund der bewerbung ist, faqlls sich der TE um nen Job bewirbt sollte er es lassen das beizulegen, ist es aber für eine lehre oder so warum denn nicht zeigt zumindest das er nicht ganz unbedarft ist und das ihm das Thema interessiert
Aber der TE wird sicher was zu sagen können
-
Ich Bewerbe mich auf eine Lehrstelle und wollte mit dem Programm zeigen, dass ich schon ein paar Vorkenntnisse in der objektorientierten Programmierung und Zeigern besitze.
Wollte dann noch die Strings durch Char Arrays ersetzen, um zu zeigen, dass ich auch das Problem "Übergabe von Arrays an Funktionen" zu lösen weiß.
Ich hoffe, dass ich damit den meisten Bewerbern voraus bin
Falls ihr noch eine, halbwegs sinnvolle, Projektidee habt, welche auf meinem Niveau ist und einen Platz in meiner Bewerbung finden könnte, wäre ich ebenfalls sehr dankbar.
MfG
RapistseinHobby
EDIT:
Ein Projekt, in dem die Rekursion ihren Nutzen findet, wäre z.B super. Ich denke, damit kann man auch etwas Eindruck schinden. Nur fällt mir nichts ein.
-
Ich würde strings lassen, da sie objektorientiert sind.
Zur Rekursion: Baue einen Parser für Mathematische Ausdrücke wie 3 + 6 * 7, nur mit Grundrechnungsarten. Alternativ kannst du auch nen Stackrechner bauen, ist ohne Rekursion machbar und einfacher.
-
Die Sache mit dem Parser hört sich sehr kompliziert an. Ich habe schon versucht mir über google ein Bild, über die Umsetzung eines solchen Parsers, zu verschaffen, bin aber noch nicht schlauer geworden.
Habe mich aber auch nur kurz damit beschäftigt, da ich zuerst mein Programm fertig bekommen wollte. Wie der Zufall es wollte, bekam ich das Buch "C++ von A bis Z" von meinem Vater geschenkt. Nach 200Seiten kam ich dann auf ein Beispielprojekt, in welchem dargestellt wurde, wie man solche Listen, anhand von Strukturen, verwirklicht.
Den Quellcode bin ich dann so lange durchgegangen bis ich alles verstanden habe. Dann habe ich mein Programm einfach mal komplett neu geschrieben und mein, neu erworbenes, wissen mit eingebracht.
Das Ergebnis ist folgendes:
#pragma once #include <string> // Neue Klasse vom Typ Personen class Personen{ private: std::string vName, nName; std::string gebDat; std::string strasse; int hausNr; std::string stadt; int plz; int vorwahl, rufNr; public: //Deklaration eines Zeigers, welcher auf das nächste Objekt der Liste zeigt Personen* next; //Methoden-Deklaration Personen(); ~Personen(void); void ausgabe(void); bool vergleich(std::string vorName, std::string nachName); };
/* Personen.cpp */ #include "Personen.h" #include <iostream> using namespace std; //Methoden-Definition des Konstruktors //Der Konstruktor wird zum anlegen neuer Objekte verwendet Personen::Personen(){ cout << "Vorname: "; cin >> this->vName; cin.ignore(); cout << "Nachname: "; cin >> this->nName; cin.ignore(); cout << "Geburtstadum (dd.mm.yyyy): "; cin >> this->gebDat; cin.ignore(); cout << "Strasse: "; cin >> this->strasse; cin.ignore(); cout << "Hausnr.: "; cin >> this->hausNr; cin.ignore(); cout << "Stadt: "; cin >> this->stadt; cin.ignore(); cout << "Postleitzahl: "; cin >> this->plz; cin.ignore(); cout << "Vorwahl: "; cin >> this->vorwahl; cin.ignore(); cout << "Rufnr.: "; cin >> this->rufNr; cin.ignore(); next = 0; } //Methoden-Definiton des Dekonstruktors //Der Dekonstruktor wird zum entfernen bestehender Objekte verwendet Personen::~Personen(void){ } void Personen::ausgabe(void){ cout << "Vorname:\t" << this->vName << endl; cout << "Nachname:\t" << this->nName << endl; cout << "Geburtsdatum:\t" << this->gebDat << endl; cout << "Strasse:\t" << this->strasse << endl; cout << "Hausnr.:\t" << this->hausNr << endl; cout << "Stadt:\t\t" << this->stadt << endl; cout << "Postleitzahl:\t" << this->plz << endl; cout << "Rufnummer:\t" << this->vorwahl << "//" << this->rufNr << endl; } bool Personen::vergleich(string vorName, string nachName){ if(vorName == this->vName && nachName == this->nName) return true; else return false; }
/* main.cpp */ #include "Personen.h" #include <iostream> using namespace std; //Funktions-Prototypen Personen* newPerson(Personen* anfang); Personen* delPerson(Personen* anfang); void showPerson(Personen* anfang); int main(void){ Personen* anfang = 0; //Anfang (Anker) der Liste int auswahl; do{ cout << "1 - Neuen Eintrag erstellen" << endl; cout << "2 - Bestehenden Eintrag entfernen" << endl; cout << "3 - Bestehende Eintraege auflisten" << endl; cout << "4 - Programm beenden" << endl; cout << "Ihre Auswahl: "; cin >> auswahl; switch(auswahl){ case 1: anfang = newPerson(anfang); break; case 2: anfang = delPerson(anfang); break; case 3: showPerson(anfang); break; case 4: break; default: cout << "Falsche Eingabe!" << endl; } }while(auswahl != 4); return 0; } Personen* newPerson(Personen* anfang){ Personen* node = 0; //Es ist noch kein Objekt in der Liste, //also wird das erste Objekt angelegt if(anfang == 0){ anfang = new Personen; return anfang; } //Es sind schon Objekte in der Liste vorhanden, //also wird das neue Objekt hinten angehängt else{ Personen* newNode = 0; node = anfang; while(node->next != 0) node=node->next; newNode = new Personen; node->next = newNode; delete delNode; return anfang; } } Personen* delPerson(Personen* anfang){ string vName, nName; cout << "Bitte den Vornamen der zu loeschenden Person eingeben: "; cin >> vName; cin.ignore(); cout << "Bitte den Nachnamen der zu loeschenden Person eingeben: "; cin >> nName; cin.ignore(); if(anfang == 0){ cout << "Die Liste ist leer" << endl; return anfang; } //Wenn das erste Objekt gesucht wird: if(anfang->vergleich(vName, nName)){ Personen* delNode = anfang; if(anfang->next != 0) anfang = anfang->next; delete delNode; } //Die komplette Liste durchsuchen else{ Personen* delNode; Personen* node = anfang; //Die Liste durcharbeiten so langeder Folgeeintrag, des gesuchten Objektes, //!= 0 ist oder eine Übereinstimmung mit der Eingabe gefunden wurde while(node->next != 0 && !(node->next->vergleich(vName, nName))) node = node->next; if(node->next == 0) cout << "Diese Person existiert nicht" << endl; else{ //Das zu löschende Element an delNode geben delNode = node->next; //Das Folgeobjekt in bufNode zwischenspeichern Personen* bufNode = delNode->next; //Das Folgeobjekt and das voherige Objekt geben (???) node->next = bufNode; } } return anfang; } void showPerson(Personen* node){ if(node == 0){ cout << "Die Liste ist leer" << endl; } else{ cout << "1." << endl; node->ausgabe(); for(int i = 0; node->next != 0; i++){ node = node->next; cout << i+2 << "." << endl; node->ausgabe(); } } }
Sollte etwas unsauber programmiert sein, sollten Kommentare fehlen oder gar falsch sein (dann habe ich etwas falsch verstanden) wäre es schön, wenn ihr mich drauf aufmerksam machen könntet. Verbesserungsvorschläge nehme ich immer gern und danked an
MfG
RisH