WS 2011/2012 Stephan Gimbel Repetitorium PAD 1+2 Übungsblatt Gran Turismo Cars - WS 11/12 Empfehlung: Arbeiten Sie in kleinen Schritten und sorgen Sie dafür, dass Sie jederzeit ein lauffähiges Anwendungssystem haben. Allgemeine Vorgaben: Keine globalen Variablen/Objekte, Verwendung der vorgegebenen Bezeichner ist verpflichtend, Eigene Bezeichner sind selbsterklärend; Kommentare nur wenn nötig, Principle of least privilege (z.b. const-correctness ), sowie KISS ist zu beachten. Aufgabenstellung: Gegeben ist eine Ascii-Datei die verschiedene Daten von Autos beinhaltet. Entwerfen Sie ein Programm welches die Datei einlesen und wieder schreiben kann und die Daten vorerst in einem geeigneten Container (std::vector<gtcar*>) speichert. Entwerfen Sie dazu die Klasse GTCar gemäß unten stehendem UML-Diagramm. 1
Klasse GTCar Überladen Sie weiterhin den Ausgabeoperator operator<< global für Objekte vom Typ GTCar, so dass die Ausgabe mittels cout << GTCar erfolgen kann. Besonderheiten der Methoden sind: Benutzen Sie für die Ausgabe (operator<<) eines GTCars auf der Konsole geeignete Strommanipulatoren, damit sie eine tabellarische Ausgabe erhalten. hpgreater und yearhpgreater dienen als statische Methoden (warum statisch?) dem Sortieralgorithmus sort aus der STL, die durch einen Function-Pointer übergeben werden. hpgreater soll nach HP/PS sortieren, yearhpgreater nach dem Jahr und innerhalb des Jahres nach HP/PS. operator< dient zum Vergleich zweier GTCars für den Sortieralgorithmus sort der STL und soll zuerst nach Hersteller und dann nach Model sortieren und damit die ursprüngliche Sortierreihenfolge wieder herstellen. (Achtung! Hier wird nach chars sortiert und nicht nach einem Zahlentyp!). Überlegen Sie sich wo das Einlesen und Schreiben der Dateien erfolgen soll und welche Vor- bzw. Nachteile dies hat. Im Zweifelsfall, erstellen Sie eine Klasse CarIO als Schnittstelle. Klasse Manager Zur Steuerung Ihres Programms, entwerfen Sie die Klasse Manager und darin die Methode run() welche den kompletten Ablauf ihres Programms steuert. Die Funktion main reduziert sich damit auf: i n t main ( ) { Manager mgr ; mgr. run ( ) ; r e t u r n 0 ; } Implementieren Sie die Anzeige des unten stehenden Menüs: B i t t e a u s w aehlen : 1. D a t e i e i n l e s e n ( ASCII ) 2. D a t e i e i n l e s e n ( B i n a r y ) 3. D a t e i s c h r e i b e n ( ASCII ) 4. D a t e i s c h r e i b e n ( B i n a r y ) 5. Z e i g e Autos 6. S o r t i e r e n nach PS 7. S o r t i e r e n nach J a h r und PS 8. S o r t i e r e n nach H e r s t e l l e r und Modell ( o r g i n a l ) 9. B u b b l e s o r t ( nach H e r s t e l l e r und Modell ) 1 0. I n s e r t i o n s o r t ( nach H e r s t e l l e r und Modell ) 1 1. Q u i c k s o r t ( nach H e r s t e l l e r und Modell ) 1 2. C o n t a i n e r l o e s c h e n 0. Programm beenden I h r e Eingabe : 2
Implementierungsdetails: Implementieren Sie das Menü mit der switch-case-auswahl. Jede Aktion wird von einer Methode der Klasse Manager ausgeführt. Solange eine Aktion nicht implementiert ist, erscheint Nicht implementiert! auf der Konsole. Bei einer ungültigen Eingabe wird das Menü erneut angezeigt, bis eine gültige Aktion gewählt ist. Wenn die Aktion 5. Zeige Autos gewählt, aber noch keine Daten eingelesen wurden, so erscheint Keine Autos eingelesen! auf der Konsole. Wird eine Aktion zum lesen oder schreiben einer Datei ausgewählt, so wird der Benutzer nach einem Dateinamen gefragt. Dieser Bearbeitungsschritt kann vom Benutzer mittels ctrl-z abgebrochen werden. Dieser Abbruch wird mit der Meldung No further input! bestätigt und das Menü wird erneut angezeigt. Implementieren Sie dieses Feature mittels Exceptions. Hinweis: ctrl-z setzt das EOF- und fail-flag des IO-Systems. Bubblesort, Insertionsort und Quicksort sollten den Container nach Hersteller und innerhalb des Herstellers nach Model sortieren und damit die Originalreihenfolge wieder herstellen. Verwenden Sie dazu nicht den STL-Algorithmus sort, sondern implementieren Sie die Sortieralgorithmen selbst. Datei - cars.txt Jede Zeile der Datei cars.txt beschreibt einen vollständigen GTCar Datensatz. Die einzelnen Attribute sind durch ein ; getrennt, die Zeile durch \n terminiert. Dabei wurde folgende Reihenfolge der Attribute verwendet: Manufacturer, Model, cost, year, drive, hp, lbft, mass, pwd, wpr und origin. Lesen die Attribute ein und weisen Sie sie gemäß der erstellen Klasse GTCar einem Objekt zu (über den Konstruktor). Dynamischer Container Ersetzen Sie den bisher verwendeten Container std::vector<gtcar*> durch eine selbst geschriebene Template-Klasse Array, die Ihnen als dynamischer Container dient. Die Größe des Containers beträgt zu Anfang (sofern nicht anders an den Konstruktor übergeben) 0. Ist der Container vor dem erneuten Einfügen eines Elements voll, so wird die Größe und damit der zur Verfügung stehende Speicherplatz verdoppelt. Das Löschen von Elementen soll nicht die Maximalgröße des Containers beeinflussen, wohl aber die Anzahl der beinhalteten Elemente. Wird bei lesendem Zugriff auf ein Element außerhalb des Containers zugegriffen, so wird eine OutOfRange-Exception geworfen. Halten Sie 3
sich bei der Implementierung der Klasse Array an unten stehendes UML-Diagramm und bzgl. der Funktionalität an die Implementierung der Klasse Vector der STL, aber ohne Verwendung der selbigen! Iteratoren Erweitern Sie die Template-Klasse Array um eine nested Class Iter welche die Iteratoroperationen übernehmen. Halten Sie sich bei der Implementierung an das unten stehende UML-Diagramm. Um die Klasse nutzen zu können, vergessen Sie nicht die Klasse Array innerhalb der nested Class Iter als friend Class zu deklarieren. Weiterhin erweitern Sie die Klasse Array um folgende Methoden: Implementierungsdetails: Werden hinzugefügt, sofern benötigt. 4
Einlesen in Klassenobjekte Wird im Laufe der Woche hinzugefügt. 5