Le but de ces travaux pratiques est de créer un logiciel permettant de "gérer" l'ensemble des personnes étudiant ou travaillant à Télécom Paris. Ce logiciel sera réalisé par étapes, en començant par la conception et l'implémentation des classes principales, puis en rajoutant diverses fonctionnalités.
Concevoir l'arbre d'héritage des classes principales sur papier en spécifiant les principales méthodes, données (et types de données) qui seront utilisées par ces classes.
On tiendra compte des remarques suivantes:
il y a 2 grandes catégories de personnes présentes à l'Ecole :
les caractéristiques typiques incluent :
les fonctionnalités principales incluent:
IMPORTANT : on se limitera ici à l'essentiel sans trop entrer dans les détails l'important étant de déterminer ce qui peut être factorisé pour faciliter le choix des classes et les relations d'héritage.
a) Ecrire le header C++ (déclaration) de la classe Racine (on pourra trouver un nom plus adapté) de l'arbre d'héritage des classes. Cette classe se limitera à la gestion des coordonnées principales d'une personne : nom, prénom, age, email.
Déclarer les méthodes adéquates pour créer un objet de cette classe,
modifier ou accèder à ses champs et afficher le contenu global de l'objet
à l'écran (avec les intitulés correspondants).
Remarques:
b) Implementer cette classe (dans un fichier .cc). Le compiler avec g++ et corriger les (éventuelles !) erreurs de syntaxe.
c) Ecrire un petit programme de test qui crée un objet et permette d'initialiser ou modifier son contenu et de l'afficher à l'écran.
a) Ecrire le header correspondant (utiliser des fichiers disctincts
pour les diverses classes).
On prendra en compte: le type de cursus, la longueur du cursus,
ainsi que l'année actuelle dans le cursus.
b) Ecrire et compiler le fichier d'implémentation correspondant puis tester les deux classes déjà implémentées. Pour ce faire, écrire un Makefile puis utiliser la commande make (on pourra s'inspirer de cet exemple de Makefile ; attention ne pas faire de coupé-collé (à cause des tabulations) mais sauvegarder via les commandes du navigateur).
Même principe que précédemment, les caractéristiques d'un employé étant son département et son bureau.
On veut maintenant pouvoir gérer géneriquement une liste d'étudiants et d'employés. On commencera pour ce faire par utiliser un tableau de pointeurs que l'on initialisera de manière appropriée dans un programme de test.
Ecrire une fonction qui permette d'afficher le contenu complet de tous
les éléments contenus dans la liste, quel que soit leur type (les
informations disponibles n'étant pas les mêmes pour un étudiant ou un employé).
Cette fonction devra respecter le principe d'encapsulation (pas d'accès
direct aux champs des objets par une fonction non-membre) et on évitera
toute duplication inutile de code.
Comment s'appelle la propriété, caractéristique de l'OO que nous devrons employer ? Comment les méthodes doivent-elles être déclarées pour que cette propriété soit effective en C++ ?
Remarque : la gestion générique de la liste devra apparaître dans votre programme final (éventuellement sous une forme modifiée). Ne supprimez pas le code correspondant en faisant les questions suivantes !
On veut maintenant spécialiser la classe Etudiant en définissant la sous-classe Eleve. Une caractérisque des élèves est qu'ils suivent des UEs qui sont sanctionnées par des notes. Faire en sorte que l'on puisse associer une liste de notes à un élève (seulement les notes, pour simplifier on ne tiendra pas compte des noms des UEs).
Ces notes seront stockées dans l'"Eleve" en utilisant un tableau (pas un vecteur de la STL). On définira:
Les autres sous-catégories d'Etudiants (pas déclaréees pour l'instant) peuvent aussi avoir des notes. Mais celles-ci ne sont pas calculées de la même manière (ils ne suivent pas forcement des UEs, etc.).
Rajouter à la classe Etudiant une méthode qui retourne la note globale. Son calcul étant indéfini au niveau de cette classe, utiliser une méthode abstraite. Qu'est-il alors nécessaire de faire dans les sous-classes de Etudiant ? Le faire dans le cas de la classe Eleve (en calculant la moyenne des notes du tableau).
La méthode d'affichage devra également afficher la moyenne et les différentes notes du tableau.
Contrairement à Java, C++ ne propose pas en standard de "garbage collector" pour récupérer la mémoire dynamique précédemment allouée et qui n'est plus utilisée (= qui n'est plus référencée par aucun pointeur).
Que faut-il faire pour détruire correctement les objets (sans fuite mémoire ni "segmentation fault" !). Rajoutez le code nécessaire et faites quelques tests mélangeant destruction et construction d'objets.
Question: les classes comportant des méthodes virtuelles doivent, logiquement, avoir des destructeurs virtuels. Pourquoi ?
(Attention : cette question est importante : elle comprend 2 parties qui doivent être faites en même temps pour gagner du temps)
a) Vérifiez que vous avez correctement implémenté les règles de constance dans les classes déja réalisées. Citez les 3 cas de figures ou le mot-clé const doit être utilisé. Modifiez votre code en conséquence partout où c'est nécessaire.
b) Vérifiez également que vous avez utilisé le passage par référence des arguments des méthodes chaque fois que cela était nécessaire.
Question: comment imposer qu'un objet créé avec new soit à valeur constante (par exemple un objet de classe Eleve dans votre fonction main()). Que se passerait'il si on essayait de lui appliquer la methode qui change les notes d'un élève ? Même question pour la méthode qui permet d'afficher son contenu. Pourquoi ?
Vos objets contiennent probablement des pointeurs (typiquement vers le tableau de notes). Il est donc dangereux de les recopier par simple affectation (les variables d'instances des 2 objets pointeraient vers les mêmes valeurs).
Questions:
Rajoutez le code correspondant dans vos classes.
Réécrire l'étape 4 en utilisant les vecteurs puis les listes chaînées de la STL.
Rajouter les fonctionnalités d'entrées-sorties manquantes : lecture au clavier des champs des classes et lecture / écriture sur un fichier. Pensez à bien modulariser votre code et à respecter les principes de l'orienté objet.
Note: on pourra éventuellement utiliser des ofstream et des ifstrems (voir le lien Manuel des librairies C++ de Sun ou ... le Web!)
Question libre : rajoutez toute fonctionnalité qui vous semblerait utile (comme par exemple la gestion des exceptions pour gérer les cas d'erreurs).
Pensez à utiliser la commande rendu-tp (SVP pas de rendu
de TP par email !).
Algorithme:
cd le-bon-repertoire # faire le menage (pas trop tout de même!) # penser a mettre un README rendu-tp inf224-cpp votre-login
Notez que cette commande copie également les sous-répertoires. Evitez de l'activer plusieurs fois (ou depuis un répertoire erroné ou avec un mauvais nom de login !)
Le fichier README doit indiquer les étapes réalisées et contenir les réponses aux questions correspondantes ainsi que les explications qui vous sembleront utiles (tout en restant concis : ce texte n'a pas besoin d'être très long).
Remarque: Ce fichier doit être en format texte standard ou en PDF. Evitez SVP:
| home page | page cours | Eric Lecolinet - ENST / INFRES - http://www.enst.fr/~elc |