Récapitulatif - Système de gestion d'étudiants
Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 39 sur 104.
Il est temps de mettre vos connaissances en matière d'encapsulation en pratique ! Dans ce défi, vous allez construire un Système de Dossiers Étudiants qui démontre l'utilisation appropriée des spécificateurs d'accès, de la dissimulation d'informations et des classes imbriquées.
Votre système gérera les données des étudiants selon ces principes d'encapsulation :
- Membres de données privés pour protéger les informations sensibles comme les notes et les identifiants d'étudiants
- Interface publique avec des accesseurs (getters) et des mutateurs (setters) contrôlés
- Une classe imbriquée pour représenter les notes de cours individuelles, gardant ce détail d'implémentation contenu au sein de la classe étudiant
Voici la structure que vous allez implémenter :
class Student {
public:
class Grade { // Nested class for course grades
// ...
};
// Public interface for interacting with student data
private:
std::string name;
int studentId;
// Collection of grades
};Ce défi combine tout ce qui a été abordé dans ce chapitre : choisir les niveaux d'accès appropriés, cacher les détails d'implémentation derrière une interface propre, et utiliser des classes imbriquées pour organiser les types liés. Réfléchissez bien à ce qui doit être accessible et à ce qui doit rester caché.
Défi
FacileConstruisons un système de dossiers d'étudiants qui rassemble tout ce que vous avez appris sur l'encapsulation. Vous allez créer un système où les données des étudiants sont correctement protégées, les notes sont gérées via une classe imbriquée, et toutes les interactions se font par une interface publique propre.
Vous allez créer deux fichiers pour organiser votre code :
Student.h: Définissez une classeStudentqui démontre une encapsulation appropriée avec une classe imbriquéeGrade.Votre classe imbriquée
Grade(déclarée dans la section publique deStudent) doit stocker un nom de cours (string) et un score (double). Donnez-lui un constructeur qui prend les deux valeurs, et fournissez les méthodesgetCourseName()etgetScore()pour accéder aux données. La classeGradegarde ses données privées — même si elle est imbriquée dansStudent, elle conserve sa propre encapsulation.La classe
Studentdoit avoir des membres privés pour le nom de l'étudiant (string), l'ID de l'étudiant (int), et une collection de pointeursGrade. Fournissez :- Un constructeur qui prend le nom et l'ID de l'étudiant
- Des getters
getName()etgetStudentId()(tous deux const) - Une méthode
addGrade(const std::string& course, double score)qui crée un nouveauGradeet l'ajoute au dossier de l'étudiant (ajoutez-le uniquement si le score est compris entre 0 et 100 inclus) - Une méthode
getAverageGrade()(const) qui calcule et retourne la moyenne de toutes les notes, ou 0.0 si aucune note n'existe - Une méthode
displayRecord()(const) qui affiche le dossier complet de l'étudiant
N'oubliez pas de libérer les notes allouées dynamiquement dans le destructeur, et d'inclure les gardes d'en-tête appropriés.
main.cpp: Lisez un nom d'étudiant, un ID d'étudiant et trois notes de cours à partir de l'entrée. Le format d'entrée sera de cinq lignes : le nom, l'ID, puis trois lignes contenant chacune un nom de cours et un score séparés par un espace (par exemple,Math 95.5).Créez un
Studentavec le nom et l'ID, ajoutez les trois notes, puis affichez le dossier complet.Le format de sortie pour
displayRecord()doit être :Student: <name> (ID: <id>) Grades: <course1>: <score1> <course2>: <score2> <course3>: <score3> Average: <average>
Formatez tous les scores et la moyenne avec une décimale en utilisant std::fixed et std::setprecision(1) de <iomanip>. Convertissez l'ID en utilisant std::stoi() et les scores en utilisant std::stod().
Ce défi combine des membres de données privés, des getters publics, des setters contrôlés avec validation et une classe imbriquée — le tout travaillant ensemble pour créer un système de dossiers d'étudiants bien encapsulé.
Aide-mémoire
L'encapsulation combine les spécificateurs d'accès, le masquage d'informations et les classes imbriquées pour protéger les données et organiser le code.
Spécificateurs d'accès pour la protection des données
Utilisez private pour les membres de données sensibles et public pour l'interface :
class Student {
public:
// Méthodes d'interface publique
private:
std::string name;
int studentId;
// Autres données privées
};Classes imbriquées
Les classes imbriquées organisent les types liés au sein d'une classe, tout en conservant leur propre encapsulation :
class Student {
public:
class Grade { // Classe imbriquée
private:
std::string courseName;
double score;
public:
Grade(const std::string& course, double s)
: courseName(course), score(s) {}
std::string getCourseName() const { return courseName; }
double getScore() const { return score; }
};
private:
std::vector<Grade*> grades;
};Accès contrôlé avec validation
Les méthodes peuvent valider les données avant de modifier les membres privés :
void addGrade(const std::string& course, double score) {
if (score >= 0 && score <= 100) {
grades.push_back(new Grade(course, score));
}
}Méthodes Const
Marquez les méthodes qui ne modifient pas les données comme const :
std::string getName() const { return name; }
double getAverageGrade() const {
// Calculer et retourner la moyenne
}Gestion de la mémoire
Libérez les objets alloués dynamiquement dans le destructeur :
~Student() {
for (Grade* grade : grades) {
delete grade;
}
}Essayez vous-même
#include <iostream>
#include <string>
#include <sstream>
#include "Student.h"
int main() {
// Lire le nom de l'étudiant
std::string name;
std::getline(std::cin, name);
// Lire l'identifiant de l'étudiant
std::string idStr;
std::getline(std::cin, idStr);
int studentId = std::stoi(idStr);
// Lire trois notes de cours (format : "CourseName Score")
std::string line1, line2, line3;
std::getline(std::cin, line1);
std::getline(std::cin, line2);
std::getline(std::cin, line3);
// TODO: Analyser chaque ligne pour extraire le nom du cours et la note
// Utiliser std::stod() pour convertir les chaînes de caractères de notes en doubles
// TODO: Créer un objet Student avec le nom et l'identifiant
// TODO: Ajouter les trois notes à l'étudiant
// TODO: Afficher le dossier complet de l'étudiant
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique