Wiederholung – Studierendenverwaltungssystem
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 39 von 104.
Jetzt ist es an der Zeit, dein Wissen über Kapselung in die Praxis umzusetzen! In dieser Herausforderung erstellst du ein Student Records System, das die korrekte Verwendung von Zugriffsbezeichnern, Informationsverbergung und verschachtelten Klassen demonstriert.
Dein System verwaltet Studentendaten nach diesen Kapselungsprinzipien:
- Private Datenelemente, um sensible Informationen wie Noten und Studenten-IDs zu schützen
- Öffentliche Schnittstelle mit Gettern und kontrollierten Settern
- Eine verschachtelte Klasse zur Darstellung der Noten einzelner Kurse, sodass dieses Implementierungsdetail innerhalb der Studentenklasse gekapselt bleibt
Diese Struktur wirst du implementieren:
class Student {
public:
class Grade { // Verschachtelte Klasse für Kursnoten
// ...
};
// Öffentliche Schnittstelle für die Interaktion mit Studentendaten
private:
std::string name;
int studentId;
// Sammlung von Noten
};Diese Herausforderung vereint alles aus diesem Kapitel: die Auswahl geeigneter Zugriffsebenen, das Verbergen von Implementierungsdetails hinter einer klaren Schnittstelle und die Verwendung verschachtelter Klassen zur Organisation verwandter Typen. Überlege sorgfältig, was zugänglich sein sollte und was verborgen bleiben sollte.
Aufgabe
EinfachLass uns ein Studentenverwaltungssystem erstellen, das alles zusammenführt, was du über Kapselung gelernt hast. Du erstellst ein System, in dem Studentendaten ordnungsgemäß geschützt werden, Noten über eine verschachtelte Klasse verwaltet werden und alle Interaktionen über eine saubere öffentliche Schnittstelle erfolgen.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
Student.h: Definiere eineStudent-Klasse, die ordnungsgemäße Kapselung mit einer verschachteltenGrade-Klasse demonstriert.Deine verschachtelte
Grade-Klasse (die im öffentlichen Abschnitt vonStudentdeklariert wird) sollte einen Kursnamen (String) und eine Punktzahl (Double) speichern. Gib ihr einen Konstruktor, der beide Werte übernimmt, und stelle die MethodengetCourseName()undgetScore()bereit, um auf die Daten zuzugreifen. DieGrade-Klasse hält ihre Daten privat. Obwohl sie innerhalb vonStudentverschachtelt ist, behält sie ihre eigene Kapselung bei.Die
Student-Klasse sollte private Member für den Namen des Studenten (String), die Studenten-ID (Int) und eine Sammlung vonGrade-Zeigern besitzen. Stelle Folgendes bereit:- Einen Konstruktor, der den Namen und die Studenten-ID übernimmt
- Getter
getName()undgetStudentId()(beide const) - Eine Methode
addGrade(const std::string& course, double score), die eine neueGradeerstellt und sie zum Datensatz des Studenten hinzufügt (nur hinzufügen, wenn die Punktzahl zwischen 0 und 100 einschließlich liegt) - Eine Methode
getAverageGrade()(const), die den Durchschnitt aller Noten berechnet und zurückgibt oder 0.0, wenn keine Noten vorhanden sind - Eine Methode
displayRecord()(const), die den vollständigen Datensatz des Studenten anzeigt
Vergiss nicht, die dynamisch zugewiesenen Noten im Destruktor freizugeben und geeignete Header Guards einzubinden.
main.cpp: Lies einen Studentennamen, eine Studenten-ID und die Noten für drei Kurse aus der Eingabe ein. Das Eingabeformat besteht aus fünf Zeilen: Name, ID und anschließend drei Zeilen, die jeweils einen Kursnamen und eine durch ein Leerzeichen getrennte Punktzahl enthalten (z. B.Math 95.5).Erstelle einen
Studentmit dem Namen und der ID, füge alle drei Noten hinzu und zeige anschließend den vollständigen Datensatz an.Das Ausgabeformat für
displayRecord()sollte folgendermaßen aussehen:Student: <name> (ID: <id>) Grades: <course1>: <score1> <course2>: <score2> <course3>: <score3> Average: <average>
Formatiere alle Punktzahlen und den Durchschnitt mit einer Dezimalstelle unter Verwendung von std::fixed und std::setprecision(1) aus <iomanip>. Konvertiere die ID mit std::stoi() und die Punktzahlen mit std::stod().
Diese Herausforderung kombiniert private Datenmember, öffentliche Getter, kontrollierte Setter mit Validierung und eine verschachtelte Klasse: Alles arbeitet zusammen, um ein gut gekapseltes Studentenverwaltungssystem zu erstellen.
Probier es selbst
#include <iostream>
#include <string>
#include <sstream>
#include "Student.h"
int main() {
// Studentenname lesen
std::string name;
std::getline(std::cin, name);
// Studenten-ID lesen
std::string idStr;
std::getline(std::cin, idStr);
int studentId = std::stoi(idStr);
// Drei Kursnoten lesen (Format: "CourseName Score")
std::string line1, line2, line3;
std::getline(std::cin, line1);
std::getline(std::cin, line2);
std::getline(std::cin, line3);
// TODO: Jede Zeile parsen, um Kursname und Punktzahl zu extrahieren
// Verwende std::stod(), um Punktzahl-Strings in Doubles umzuwandeln
// TODO: Erstelle ein Student-Objekt mit dem Namen und der ID
// TODO: Füge alle drei Noten zum Studenten hinzu
// TODO: Zeige den vollständigen Studenteneintrag an
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler