Beispiel für Klassenanwendung inkl. map
-
Holla,
Da ich momentan dabei bin mich in das Thema Klassen einzulesen und es irgendwie noch am Verständnis hapert, möchte ich darum bitten dass mir jemand ein Beispiel für die professionelle Anwendung einer oder mehrerer Klassen gibt.Persönlich habe ich als Beispiel eine Lagerverwaltung nehmen wollen, in der ich dann z.B die Klassen 'Werkstoffe', 'Werkzeuge' und 'Hilfsmitte' verwendet hätten.
Allerdings stieß ich dabei auf das das Problem dass für jede Artikelnummer eine eigene Varaiable angelegt werden müsste, was mir irgendwie unverhältnismäig erscheint.
class kWerkzeug { public: string Ort ; int Anzahl ; kWerkzeug() : Anzahl(0) { } int Hinzufuegen () ; int Abrufen () ; }; kWerkzeug hammerGruen, hammerBlau, Schraubendreher_klein, Schraubendreher_groß [...]edit:
Ich bin auf ein neues Problem gestoßen:
Wenn das Programm alle Waren kennt, wie lasse ich es eine gesamtübersicht ausgeben? Anders gefragt, wie lese ich alle Objekte einer Klasse ein?
-
Ein einigermaßen sinnvolles Beispiel für Klassen und so:
class Article { public: int Id; std::string Name; int Place; size_t Count; Article() : Id(-1) , Name("unknown") , Place(-1) , Count(0) { } virtual ~Article() {} virtual void print() { cout << Id << " [Artikel]: " << Name << ", " << Place << ", " << Count << endl; } }; class Material : public Article { public: //Werkstoff-Eigenschaften.. Material() { } void print() { cout << Id << " [Werkstoff]: " << Name << ", " << Place << ", " << Count << endl; } }; class Tool : public Article { public: //Werkzeug-Eigenschaften.. Tool() { } void print() { cout << Id << " [Werkzeug]: " << Name << ", " << Place << ", " << Count << endl; } }; class Warehouse { public: std::vector<Article*> Articles; void printArticleList() { for (size_t i = 0; i < Articles.size(); ++i) { Articles[i]->print(); } } }; Warehouse w; w.Articles.push_back(new Tool()); w.printArticleList();
-
Ich würde die Werkzeuge auch eher abstrakt verwalten. Du brauchst ja die Werkzeuge nicht zu unterscheiden. Sondern bist nur an ein paar Daten jeweils interssiert. Also kannst du gut eine abstraktere Klasse, wie schon oben genannt "Article" nennen und dann da die Daten reinschreiben. (Name, Preis, Menge usw.)
Und dann kannst du die gewünschten Artiklen in einer Datenbank speichern (oder für den Anfang mal einfach eine Textdatei) und dann beim Programmstart diese Daten einlesen und das komplette Warenhaus erzeugen. Dann kannst du da ja die Datensätze bearbeiten, oder auslesen und dann wieder zurückspeichern.
-
In meinen Augen macht es keinen Sinn, für jeden Artikel eine eigene Klasse zu benutzen, schliesslich benutzt du die Objekte nicht wegen ihrer Funktionalität sondern um Metadaten über die Objekte abzulegen. Daher bietet sich eine Klasse Article an, die Daten speichert, die alle Artikel gemeinsam haben (z.B. Name, Artikelnummer, vorhandene Menge, Lagerort), zusätzlich sollten eine beliebige Anzahl von Tags an den Artikel heftbar gemacht werden, um individuelle Eigenschaften des Artikels beschreiben (und danach suchen) zu können.
#include <string> #include <vector> class Article { // Artikelnummer std::string ID_; // Klartext Artikelname std::string Name_; // Anzahl der verfügbaren Artikel unsigned int Available_; // Vektor mit (einfachsten) Tags std::vector<std::string> > Tags_; ... };
-
Vielen Dank,
Ich habe nun auf eine einzige Klasse umgeformt. Da es sich aber um eine Lagerverwaltung handeln soll, müsste man die Daten natürlich irgendwie zwischenspeichern. Da ich mit Datenbanken wie SQL noch nicht umgehen kann bleibt mir nur dass ganze via Textdatei zu lösen. Dabei stoße ich aber auf das Problem dass die textdatei um ein erfolgreiches Auslesen möglich zu machen in etwa so aussehen müsste:
Artikel_name Artikel_id Artikel_preis Artikel_name Artikel_id [...]Aißerdem muss der Nutzer selbstständig neue Objekte hinzufügen können ohne den Quelltext zu ändern, zum Beispiel wenn ein neuer Artikel zum Sortiment hinzugefügt wird. Ist das realisierbar?
-
serbud schrieb:
Ist das realisierbar?
Klar. Du hast doch gerade schon gesagt, wie man das machen könnte
.
-
Nunja, meine Methode wäre aber auf gut Deutsch ziemlicher Mist weil unübersichtlich.
Ich dachte mehr an etwas wie
Artikel_name, Artikel_id Artikel_name, Artikel_idDa frage ich mich aber wie ich innerhalb einer Zeile verschiedene TYpen lesen kann.
-
Ach so, dir geht es um ein gutes Format. Das ist doch kein Problem, da ist nur ein bisschen Phantasie gefragt.
Wenn man formatierte Daten aus Streams lesen will, nimmt man dazu normalerweise den Operator >>.
-
Nach meiner bisherigen Annahme liest der >> Operator ähnlich wie getline() aber eine ganze Zeile ein und springt dann zur nächsten? Wie teile ich ihm mit dass er z.B nur bis zu einem Komma lesen soll und wenn in der Zeile keines mehr vorhanden ist in die nächste springen soll?
-
Du kannst getline() als dritten Parameter den gewünschten Delimiter mitgeben:
http://www.cplusplus.com/reference/string/getline/
-
serbud schrieb:
Nach meiner bisherigen Annahme liest der >> Operator ähnlich wie getline() aber eine ganze Zeile ein und springt dann zur nächsten? Wie teile ich ihm mit dass er z.B nur bis zu einem Komma lesen soll und wenn in der Zeile keines mehr vorhanden ist in die nächste springen soll?
Deine Annahme ist (zumindest für std::string) falsch. Das genaue Verhalten liegt natürlich an der Definition des Operators (den man für eigene Klassen auch selber definieren kann) für die eingebauten Datentypen und die Typen aus der Standardbibliothek wird üblicherweise bis zum nächsten whitespace gelesen*.
In deinem Fall bietet sich natürlich eine Überladung des >> Operators für deine Klasse an, die dann intern mehrmals "istream >> string" benutzt.
*: Dieses Verhalten kann man übrigens mit entsprechenden Flags ändern.