Archiv verlassen und diese Seite im Standarddesign anzeigen : Frage zu einer Praktikumsaufgabe in C++
Hallo!
Ich habe eine kleine C++ Praktikumsaufgaben bekommen. Leider habe ich bis jetzt praktisch noch nie was mit c++ gemacht (das Semester ist noch jung ;) )
Also wir sollen ein kleines Programm schreiben mit dem man seine Praktikas verwalten kann. Uns wurde gesagt das wir mindestens zwei Klassen brauchen eine Klasse Student und eine Klasse Praktika. Achja Natürlich noch ein starter.cpp. Jetzt bin ich grad am überlegen wie ich diese zwei Klassen verbinden kann so das ich ein Objekt bekomme in dem ich dann die Daten entgegennehmen kann und eventuell in ein File abspeichern kann. Ich brauch einfach nur einen kleinen Denkanstoß da dies mein erstes OOP Programm ist.
mfg Janosch2
SeeksTheMoon
10-10-2004, 20:22
Als erstes kannst Du Dir immer die grundlegende Frage stellen:
"Woraus besteht ein Objekt (Variablen), was soll es können (Methoden)"
Dann kannst Du Dir um Vererbung und andere Beziehungen Gedanken machen, z.B. mit der Frage:
"Welche Objekte enthalten gleiche Elemente" (Erstellung von Basisklassen) oder "Welche Objekte interagieren miteinander" (Parameter bei Methoden, Zeigerlisten, public/private/protected usw)
Ein Praktikum hat einen Namen, mehrere Teilnehmer (= Zeiger(liste) auf Studenten), usw.
Ein Student hat z.B. einen Namen, eine Matrikelnummer usw. und kann an einem (oder mehreren?) Praktika (Zeiger auf selbiges) teilnehmen.
Wenn Du willst, kannst Du noch eine abstrakte Basisklasse erstellen von der beide den Namen erben.
Die Startklasse besitzt nur die main(), erstellt die nötigen Studenten+Praktikum-Objekte und kann sonstige Dinge wie Programmsteuerung übernehmen.
THX erstmal :D
So jetzt habe ich ein Objekt Student und ein Objekt Praktikum. Wie kann ich jetzt eine Beziehung zwischen diesen beiden Objekten herstellen?
Mal Angenommen ich habe jetzt sagen wir mal 3 Studenten eingegeben und 4 Praktikas die diese Studenten belegen können.
So jetzt habe ich mir das ganze so überlegt. Ich leite die Klasse Praktikas von der Klasse Student ab und erstelle "1" neues Objekt bei dem ja jetzt alle Eigenschaften vorhanden sind. Jedoch bekomme ich doch jetzt ein datenüberfluss, da ja jetzt z.B. Praktikaeigenschaften mehrmals eingegeben werden müssen die gleich sind.
Student 1 hat bestanden Praktika 1 und 2
Student 2 hat bestanden Praktika 1 ,2 und 3
Student 3 hat bestanden Praktika 2 und 4
mfg janosch2
IMHO ist das eher ein gutes Beispiel für eine DB, ne übung für SQL.
Natürlich kann man's in C++ Implementieren, aber C++ ist dafür IMHo net die idealste Sprache.
SeeksTheMoon
10-10-2004, 22:16
Beziehungen machst Du in diesem Fall mit Zeigern.
Die Klasse Student bekommt eine Liste/ein Array/(sonstiges, ähnliches Konstrukt) mit bestandenen Praktika. Diese Liste (ich nenne das mal "list", ich weiß nicht welche Container Du verwenden darfst/willst) speichert Zeiger auf die Praktikumsobjekte, z.B. so:
class Student {
...
list<Praktikum*> bestandenePraktika;
...
void addPraktikum(Praktikum*); //hängt das Praktikum in die Liste ein
}
dann in der main:
int main() {
Student* stud1 = new Student();
Praktikum* prakt1 = new Praktikum();
Praktikum* prakt2 = new Praktikum();
stud1->addPraktikum(prakt1);
stud1->addPraktikum(prakt2);
...
return 0;
}
Edit: Wenn man z.B. eine Datenbankanwendung in C++ schreiben will, muss man die Datenbank ebenfalls mit C++Objekten abbilden. C++ ist deshalb sehr wohl gut für sowas geeignet.
@SeeksTheMoon
Vielen dank jetzt kann ich ja los legen. :D :D
Ich gib dir ein Virtuelles Bier aus ;)
mfg janosch2
P.S. Noch eine Letzte Frage :) Was ist das den --> <Praktikum*> bzw. was macht man da mit? Wofür stehen die größer,kleiner zeichen?
Sag ich hier das ich einen verweis auf die Klasse Praktikum haben will?
Das müste ich grad noch wiessen damit ich im Buch nachschauen kann.
locus vivendi
11-10-2004, 09:08
int main() {
Student* stud1 = new Student();
Praktikum* prakt1 = new Praktikum();
[ Wenn die Zeile direkt oberhalb fehlschlägt, wird "stud1" niemals
freigegeben werden! ]
Praktikum* prakt2 = new Praktikum();
[ Ditto mit "prakt1" + "stud1". ]
stud1->addPraktikum(prakt1);
stud1->addPraktikum(prakt2);
...
return 0;
}
Das ist also gefährlich wenn man keine Vorkehrungen für den Fall einer fehlschlagenden "new" Operation trifft. Angenommen die Klasse Student tut "das Richtige" mit den übergebenen Zeigern, dann wäre das hier Sicher:
...
int main() {
Student stud1;
stud1.addPraktikum(new Praktikum);
stud1.addPraktikum(new Praktikum);
}
Oder, wenn man vor dem Einfügen noch Operationen auf einem "Praktikum" Objekt aufrufen möchte dieses:
...
int main() {
Student stud1;
Praktikum* p_prakt1 = new Praktikum;
p_prakt1->irgend_etwas();
stud1.addPraktikum(p_prakt1);
Praktikum* p_prakt2 = new Praktikum;
p_prakt2->tue_dieses(); p_prakt2->tue_jenes();
stud1.addPraktikum(p_prakt2);
}
Aber jetzt könnte ja immer noch die Funktionen von "Praktikum" mit einer Ausnahme abbrechen. Also "richtig" sicher wird es erst wenn man es z.B. so macht:
...
int main() {
Student stud1;
std::auto_ptr<Praktikum> ap_prakt1(new Praktikum);
ap_prakt1->irgend_etwas();
stud1.addPraktikum(ap_prakt1.release() );
std::auto_ptr<Praktikum> ap_prakt2(new Pratikum);
ap_prakt2->tue_dieses(); ap_prakt2->tue_jenes();
stud1.addPraktikum(ap_prakt2.release() );
}
Moral von der Geschichte: Viele Zeiger machen auch viel Aufwand um Fehler zu vermeiden. Vielleicht wäre also folgende Modifikation in der Klasse Student sinnvoll:
class Student {
...
list<Praktikum> bestandenePraktika;
[ Speichernt nun keine Zeiger mehr ]
...
void addPraktikum(Praktikum); //hängt das Praktikum in die Liste ein
}
SeeksTheMoon
11-10-2004, 09:44
die Spitzen Klammern haben mit Templates zu tun. Ich glaube nicht dass Du in den ersten Stunden schon Templates kennen lernst, aber egal:
Man kann Methoden oder Klassen so schreiben, dass sie keinen speziellen Datentyp (wie z.B. int) aufnehmen, sondern dass das zur Laufzeit entschieden werden kann.
Das sind Templates und die spitzen Klammern sagen dem Compiler, was in eine Template-Klasse für Daten kommen sollen.
Eine verkettete Liste z.B. sollte man als Template erstellen, sonst muss man für jeden möglichen Datentyp und jede Klasse den gleichen Code nochmal schreiben und ggf speziell anpassen.
In der Standardbibliothek STL sind z.B. alle Containerklassen mit Templates realisiert.
btw: die Liste keine Zeiger speichern zu lassen, wird aber viel Speicher beanspruchen, das Programm verlangsamen und Dateien aufblähen.
peschmae
11-10-2004, 09:48
Man kann Methoden oder Klassen so schreiben, dass sie keinen speziellen Datentyp (wie z.B. int) aufnehmen, sondern dass das zur Laufzeit entschieden werden kann.
C++ Templates sind doch Compile-Time-mässig gemacht, oder?
MfG Peschmä
SeeksTheMoon
11-10-2004, 10:00
ähm, meine ich auch. Der Compiler substituiert das Template mit dem Datentyp und das geht natürlich nur zum Compile-Zeitpunkt und nicht zur Programmlaufzeit.
locus vivendi
11-10-2004, 10:27
btw: die Liste keine Zeiger speichern zu lassen, wird aber viel Speicher beanspruchen, das Programm verlangsamen und Dateien aufblähen.
Kommt drauf an. Wenn man Kopien ein und derselbe Liste hat, dann durchaus, ja. Zu einem großen Teil lassen sich Kopien aber vermeiden. Speziell in diesem Fall würde ich dazu Raten, keine Zeiger zu speichern, es sei denn es wird die Semantik von Verweisen gebraucht. Denn für ein solches "Spielzeug-Projekt" kommt es auf ein paar 100 KByte mehr oder weniger (vermutlich) nicht an.
Powered by vBulletin® Version 4.2.5 Copyright ©2025 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.