Sie haben einige Grundlagen zur objektorientierten Programmierung kennengelernt. Dazu gehören: Klassen (Deklaration, Methoden) und Objekte (Erzeugung, Methodenaufruf).
Sie können nun eine einfache Logistik-Applikation erstellen. Ihr Programm simuliert den Fuhrpark einer Speditionsfirma. Fahrzeuge werden eingesetzt, um Ware zu transportieren. Dabei fallen sowohl Kosten also auch Umsätze an. Es soll per Simulation ermittelt werden, bei welchen Rahmen-Parametern (Anzahl Fahrzeuge) das Unternehmen gewinnbringend arbeitet.
Nicht berücksichtigt werden dabei anfallende Betriebskosten neben dem Diesel (Personal, Steuern, Reparaturen) und die begrenzte Lebensdauer eines Fahrzeuges. Außen vor bleiben auch die Bündelung mehrerer Waren auf einem Fahrzeug. Auch die Angebot/Nachfrage-Relation (gibt ein Kunde überhaupt den Auftrag?) wird hier nicht simuliert. Als Optimierungsproblem gesehen, ließe sich die Simulation leicht erweitern, um mehrere Fuhrpärke zu vergleichen, oder um die Rahmenparameter (Preise etc.) zu verändern.
Unser Diskursuniversum enthält die folgenden Konzepte (Klassen). Angegeben sind die wichtigsten Eigenschaften (Elementvariablen) und Methoden (Elementfunktionen). Ergänzen Sie, wenn nötig, weitere. Belegen Sie Eigenschaften mit sinnvollen Werten bei der Initialisierung der Klassen.
(Orte mit ihren geographischen Positionen und eine Datenbank, die auch die Entfernung zwischen zwei Orten berechnen kann.) Diese Klassen werden samt Demo-Applikation zur Verfügung gestellt.
Die Klassen können kann hier heruntergeladen werden.
(hat ein zulässiges Ladegewicht (in kg), einen Preis, einen Standort, einen Benzinverbrauch (liter pro 100 km), und einen Wartungskostenaufwand (pro km). Vergeben sie im Konstruktor sinnvolle Standardwerte (defaults). Wo Standardwerte keinen Sinn machen, verlangen Sie Argumente im Konstruktor. Der anfängliche Standort jedes Fahrzeugs ist Berlin. Fahrzeuge können sämtliche Daten auf die Konsole (cout) bzw. einen Stream ausgeben. Ein Fahrzeug kann an eine andere Stelle fahren und verursacht dadurch Kosten; dies erledigt die Methode
int faehrt(Ort ziel)
(Rückgabewert: angefallene Kosten in DM.) Der Dieselpreis sollte eine globale Variable sein.
Eine Methode getStandort() liefert den Standort des Fahrzeugs. "Zugriffsschutz": Jede andere Klasse kann ein Fahrzeug an eine andere Stelle fahren (public). Der Standort des Autos kann aber nicht direkt gesetzt werden (protected).
Alle Fahrzeuge haben einen Wartungskostenaufwand von 0,10 DM / Kilometer.
(hat einen Standort und ein Gewicht in kg, das nur anfänglich gesetzt werden kann. Später kann es mit der Methode getGewicht() gelesen werden. Alternativ können Sie Ware auch einfach als "struct" sehen.
Enthält die Fahrzeuge eines Unternehmens sowie ein Kostenkonto, das im Konstruktor mit einer Geldsumme initialisiert wird. Ferner sind
Identifizieren Sie alle benötigten Klassen und deren Elemente (siehe Text). Erstellen Sie eine grafische Darstellung der Klassenhierarchie (Klassendiagramm). Es genügt, die öffentliche Elemente (Eigenschaften, Methoden) der Klassen zu erwähnen. Zeigen Sie mit Pfeilen die Beziehung zwischen den Klassen.
Jedes Rechteck steht für eine Klasse. "Student" und "Übungsleiter" sind von der Basisklasse "Benutzer" abgeleitet. Jeder Benutzer hat einen Namen und eine E-Mail-Adresse, ferner eine Instanz der Klasse "Fähigkeiten". Dazu gehören eine Sprache, allgemeine und spezifische Kenntnisse.
Es genügt eine handschriftliche Zeichnung auf Papier, die Sie beim nächsten Kurstermin mitbringen können. Wenn Sie Zugriff auf Programme wie Microsoft Visio oder Rational Rose haben, empfiehlt sich deren Benutzung.
Implementieren Sie folgendes Programm, das den Betrieb des Fuhrparks simuliert und dabei die Klassen verweden, welche Sie später noch implementieren werden. Dabei werden Waren mit den Fahrzeugen durch das Land transportiert. Die anfallenden Kosten und Umsätze werden durch die Fuhrpark-Klasse notiert.
Da sich die Fahrzeuge nach jedem Transport nicht wieder zum Betriebshof in Berlin zurückbewegen, hat die Beschaffenheit des Fuhrparks vitalen Einfluss auf den Erfolg des Geschäfts.
Nota bene: Durch Ihr Programm definieren Sie einen Test-Anwendungsfall, mit dem Sie später die Funktionalität Ihrer Fuhrpark-Klassen unter Beweis stellen können. Machen Sie sich also ZUERST Gedanken darüber, wie die Klassen nach außen hin funktionieren sollen (Schnittstelle), bevor Sie irgendwelche Innereien implementieren.
Fuhrpark speditionMueller(5000000, 0.20, 40); // Startkapital: 5 Mio DM speditionMueller.kaufeFahrzeug(CityHopper()); // einen CityHopper kaufen speditionMueller.kaufeFahrzeug( Pkw(35000) ); // einen Pkw für 35000 DM kaufen speditionMueller.kaufeFahrzeug( TransEuropeLkw() ); // einen Pkw für 35000 DM kaufen
Lassen Sie nun Ihr Programm laufen und verändern nach jedem Lauf die Zahl und Art der Fahrzeuge. Welche Fuhrparks sind erfolgreich, welche nicht?
Implementieren Sie die entworfene Klassenhierarchie in C++.
Erstellen Sie eine Datei (KlassenName.h) für die Deklaration jeder Klasse, und eine Datei für die Implementierung (KlassenName.cpp).
Beachten Sie die Verwendungsbeispiele aus der folgenden Aufgabe.
class Fuhrpark : public multimap<int, Fahrzeug> { ... }
Dann können Sie die dabei geerbte Elementfunktion "insert" in der Syntax
insert(value_type( gewicht, fahrzeug));
benutzen, um ein Fahrzeug hinzuzufügen. Sie können mit lower_bound(gewicht) das kleinste Fahrzeug herausfinden, welches das gegebene Gewicht transportieren kann. Alles weitere finden Sie in der Dokumentation zu Ihrer STL.
Die weniger elegante, aber wohl einfachere Alternative: erwähnten multimap-Container können Sie auch als Element von Fuhrpark einbinden.
Implementieren Sie für Fahrzeug und Fuhrpark einen ostream& << Operator, so dass der Zustand des Fuhrpark s auf den Bildschirm ausgegeben werden kann. So geht das:
ostream& operator<< (ostream& out, Fahrzeug& f) { … }
Sollten Sie Schwierigkeiten mit der Bewältigung der Aufgabe haben, vereinfachen Sie die Anforderungen und verwirklichen Sie erst mal ein einfacheres Programm!
... Transportiere 34497kg nach ulm. Gewinn: 4292 DM Kontostand: 6995858 Transportiere 1605kg nach münchen. Gewinn: 101 DM Kontostand: 6995959 Transportiere 10696kg nach bremen. Gewinn: 1162 DM Kontostand: 6997121 Transportiere 2404kg nach essen. Gewinn: 188 DM Kontostand: 6997309 Transportiere 36005kg nach prag. Gewinn: 3124 DM Kontostand: 7000433 Information ueber Fahrzeug: Ladegewicht: 500 Spritverbrauch: 10 Preis: 35000 Standort: stuttgart Tacho: 9701 nach 28 Fahrten Information ueber Fahrzeug: Ladegewicht: 4500 Spritverbrauch: 18 Preis: 85000 Standort: Tacho: 0 nach 0 Fahrten Information ueber Fahrzeug: Ladegewicht: 40000 Spritverbrauch: 38 Preis: 285000 Standort: prag Tacho: 467548 nach 1334 Fahrten 2067 Transporte durchgeführt. 967.7953491 Reingewinn pro Transport Programmende. Return drücken!
Lösungen müssen in einer einzelnen E-Mail an die Adresse reitter@ling.uni-potsdam.de eingereicht werden. Quelltexte sind als Anhänge mitzuliefern.
Sämtliche Quelltexte sind mit Kommentaren zu versehen. Bezeichner sollten sinnvoll sein (deutsch/englisch).