et Programmation Objet

Dimension: px
Commencer à balayer dès la page:

Download "et Programmation Objet"

Transcription

1 FACULTE POLYTECHNIQUE DE MONS Service d Informatique et Programmation Objet Mohammed Benjelloun 2 ème Bachelier Année académique

2 Table des matières Avant-propos Chap 1 : Les structures et fonctions membres Principes des structures Structures et fonctions membres Exercices Chap 2 : Les listes simplement chaînées Généralités Listes Simplement chaînées Exercices Chap3 : Les Classes Classes et objets Concept d encapsulation Création d'objets Affectation d objets Déclaration d une fonction membre Notions de constructeur et de destructeur Constructeurs par défaut Constructeur de copie Listes d initialisation des constructeurs Affectation d un objet par un autre de la même classe Tableau d objets Surcharge des opérateurs Exercices Chap4 : Les patrons et amis Patrons de fonctions Classe template : patron de classes Utilisation d un patron de classes M.BENJELLOUN Info II S. Informatique

3 4.4. Fonctions et classes amies Fonctions amies Méthodes amies Classes amies Exercices Chap5 : L'héritage Classes de base et classes dérivées Mode de dérivation Héritage public Redéfinition de membres dans la classe dérivée Redéfinition des fonctions membres Redéfinition des données membres Héritage et Constructeurs/destructeurs Polymorphisme Exercices Chap6 : La bibliothèque STL Introduction Les conteneurs Vector List Les itérateurs Les algorithmes Exercices Syllabus2d_2 : Transparents des séances d exercices M.BENJELLOUN Info II S. Informatique

4 Avant-propos Ces notes constituent le support des travaux pratiques et des exercices dans le cadre de l'enseignement du cours d'informatique II de la deuxième année de bachelier à la Faculté Polytechnique de Mons. Il représente aussi une partie du cours Programmation et Algorithmique dispensé aux étudiants d IG Charleroi. Lors des séances d'exercices, où la présence est obligatoire, un complément de matière sera abordé. Donc le présent document ne peut être considéré comme complet. Ce cours s appuie sur des notions préliminaires de programmation procédurale. La syntaxe du langage C++ ainsi que les notions fondamentales de programmation ont été étudiées durant le cours d Informatique I et sont supposées acquises. Durant ce cours, les notions fondamentales de la programmation orientée objet sont abordées. Nous commençons par un rappel sur les structures auxquelles nous introduisons les fonctions membres. Le chapitre 2 peut être considéré comme une brève introduction aux listes simplement chaînées dont le rôle est de remédier aux limitations des tableaux statiques ou dynamiques. Avec le chapitre sur les classes, généralisation de la notion de type défini par l'utilisateur, nous abordons véritablement les possibilités de "programmation (orientée) objets". Nous introduisons la définition d une classe, la notion de méthode, l encapsulation et le type de membre (publique, privé, protégé), ainsi que les notions très importantes de constructeur et de destructeur indispensables à ce type de programmation. Nous montrons aussi comment définir une famille de fonctions ou de classes paramétrées par un ou plusieurs types grâce à la notion de patron de fonctions et de classes. Par la suite nous proposons un principe propre à la programmation orientée objet : l'héritage qui permet de créer une nouvelle classe à partir d'une classe existante. Un autre concept des langages objet qui découle directement de l'héritage est le polymorphisme. Pour terminer, nous esquissons la bibliothèque STL (Standard Template Library : Bibliothèque standard générique.) qui est certainement l un des atouts de C++ et qui peut être considérée comme un outil très puissant. Comme la programmation par l exemple vaut mieux que tous les beaux discours, nous avons illustré et agrémenté ces notes, comme les Slides des séances d'exercices, de nombreux programmes permettant à l étudiant d assimiler les principales notions présentées. Tous les programmes sont fournis complets avec le résultat de leur exécution. Le code source de ces programmes est accessible sur le site Web de la Faculté. Nous ne pouvons qu insister sur la quasi-nécessité de les tester, et mieux encore de les comprendre et de les modifier. En ce qui concerne les exercices, nous incitons l étudiant à les programmer, car la programmation est un art qui s apprend en pratiquant. Vous l aurez compris, ces notes n ont pas la prétention d expliquer en détail tous les concepts du C++, mais se proposent en tant qu introduction à la programmation orientée objet. Ce syllabus ne peut donc être considéré comme autosuffisant pour apprendre tout le

5 langage C++. En effet, la matière est vaste et le temps attribué est court. Mais la programmation orientée objet, sera approfondie durant le cours de 3 ème année en préparation au master d Informatique et Gestion. Nous renvoyons, néanmoins le lecteur désireux d'en savoir plus à l'un des très nombreux ouvrages de référence sur le C++, notamment à: Claude Delannoy Programmer en langage C++, Eyrolles, 2004 ou l édition 2007 Très bon livre pour commencer le C++, livre très pédagogique et assez complet. Plusieurs chapitres sont dédiés aux composants de la bibliothèque standard du C++. John R. Hubbard Programmer en C++, Collection Schaum s Ediscience, Dunod Un ouvrage expliquant les concepts de base de la programmation C++ à l'aide d'exemples. On y trouve entre autre: Classes, Surcharge d'opérateurs, Composition et héritage, Modèles et itérateurs, C++ standard et les vecteurs, Classes conteneur. John R. Hubbard Structures de données en C++, Collection Schaum s Ediscience, Dunod Ce volume est complémentaire au précédent. Près de 455 exercices et problèmes résolus sont décortiqués pour une meilleure compréhension. On y trouve entre autre : Classes, Listes, Tables, Arbres, classes conteneurs standard, algorithmes génériques. 2 Sur le Web : Cours, tutoriels, livres électroniques et Docs sur C++ : Mega Cours C++ en français Je voudrais remercier ici les collègues du Service d'informatique qui ont pris soin de relire ces notes et de suggérer corrections et améliorations. Je suis bien conscient qu'il reste des erreurs et/ou des imprécisions. Merci au lecteur assidu de les signaler! Si vous notez la moindre erreur ou si vous souhaitez me proposer vos suggestions, n'hésitez pas à le faire à l adresse suivante : [email protected]

6 Chap 1 : Les structures et fonctions membres Ce chapitre est un prolongement du chapitre 8 du syllabus de la 1 ère année de bachelier sur l'utilisation des structures en C++. Certaines notions du chapitre 8 vont être rappelées ici, brièvement ; d'autres, complètement nouvelles comme les fonctions membres, seront introduites Principes des structures Une structure est un ensemble de variables (de types éventuellement différents), définissant un nouveau type sous un seul nom, adapté à une gestion spécifique et à une manipulation facile des données. Une structure se définit par un identificateur suivant le mot-clé struct, ainsi que par une liste de champs ou membres définis par un identificateur d'un type donné. Par exemple, pour gérer les coordonnées d'un point (abscisse et ordonnée) ou des étudiants, on pourra définir les types suivants : struct point { int x; int y; ; struct Etudiant { int Id; string Nom; ; Quant à x et y, on dit que ce sont des champs ou des membres de la structure point, alors que Nom et Id sont des champs de la structure Etudiant. On déclare ensuite des variables du type point (Etudiant) par des instructions telles que : struct point a, b; struct Etudiant Etud1, Etud2; Etudiant Etud[10] ; // a et b deux variables de type structure point // Etud est un tableau de 10 éléments de type structure Etudiant Celle-ci réserve l'emplacement pour des structures nommées a et b de type point, Etud1 et Etud2 de type Etudiant et finalement un tableau de 10 éléments de type Etudiant. L'accès aux membres de a, b ou de Etud1 et Etud2 se fait à l'aide de l'opérateur point (.). Par exemple, a.y désigne le membre y de la structure a et Etud1.Nom désigne le nom du Etudiant Etud1. Rq En C++ le mot clé struct n'est pas nécessaire devant la structure lors de la déclaration. En C++, nous allons pouvoir, dans une structure, associer aux données constituées par ses membres des méthodes qu'on nommera "fonctions membres".

7 Chap 1 : Les structures et fonctions membres Structures et fonctions membres Supposons qu en plus de la déclaration des données Id et Nom, nous souhaitions associer à la structure Etudiant deux fonctions : void Saisie() : pour saisir l identifiant et le nom d un seul Etudiant ; void Affiche() : pour afficher les information d un seul Etudiant. Voici comment nous pourrions éventuellement déclarer la structure Etudiant : struct Etudiant { int Id; string Nom; void Saisie() ; void Affiche() ; ; Dans la déclaration d'une structure, il est permis (mais généralement peu conseillé) d'introduire les données et les fonctions dans un ordre quelconque (nous avons systématiquement placé les données avant les fonctions). Le programme suivant reprend la déclaration du type Etudiant, la définition de ses fonctions membres et un exemple d utilisation dans la fonction main : #include <iostream> #include <string> using namespace std ; struct Etudiant { int Id; string Nom; void Saisie() ; // Saisir un élément void Affiche() ; ; // Définition des fonctions membres du type Etudiant ---- void Etudiant::Saisie() { cout << "donnez un identifiant : "; cin >> Id; cout << "donnez un nom : " ; cin >> Nom; void Etudiant::Affiche() { cout << " Identifiant ="<< Id << endl; cout << " Son nom : "<< Nom << endl; void main(){ Etudiant Etud3, Etud[3]; cout << "----> Etud >"<< endl; for(int i=0 ; i<3 ; i++){ Etud[i].Saisie(); Etud[i].Affiche(); cout << "----> Etud3 ---->"<< endl; Etud3.Saisie(); // accès à la fonction Saisie du Etudiant Etud1 Etud3.Affiche(); Programme 1.1.

8 Chap 1 : Les structures et fonctions membres 5 SOLUTION ----> Etud > donnez un identifiant : 0 donnez un nom : Etud0 Identifiant =0 Son nom : Etud0 donnez un identifiant : 1 donnez un nom : Etud1 Identifiant =1 Son nom : Etud1 donnez un identifiant : 2 donnez un nom : Etud222 Identifiant =2 Son nom : Etud > Etud3 ----> donnez un identifiant : 33 donnez un nom : ETUD33 Identifiant =33 Son nom : ETUD33 Dans l'en-tête, le nom de la fonction Etudiant::Saisie(), signifie que la fonction Saisie() est celle définie dans la structure Etudiant. En l'absence de ce "préfixe" (Etudiant::), nous définirions effectivement une fonction nommée Saisie(), mais celle-ci ne serait plus associée à Etudiant; il s'agirait d'une fonction "ordinaire" et non plus de la fonction membre de la structure Etudiant. Dans les fonctions Saisie() et Affiche(), il faut remarquer l utilisation de Id et du Nom qui ne sont ni des arguments de fonctions ni des variables locales. En fait, ils désignent les membres Id et Nom de la structure Etudiant. L association est réalisée par Etudiant:: de Rq l en-tête des fonctions. Voici un autre exemple utilisant cette fois ci la structure point. #include <iostream> using namespace std ; struct point { int x ; int y ; // Déclaration des fonctions membres (méthodes) void initialise(int, int) ; void affiche() ; ; void Affiche2(point A, point B){ // fonction non membre cout << "\n...je suis dans Affiche2..."<<"\n" ; A.affiche(); B.affiche(); // --- Définition des fonctions membres du type point --- void point::initialise (int abs, int ord) { x = abs ; y = ord ; void point::affiche () { cout << "Je suis en " << x << " " << y << "\n" ;

9 Chap 1 : Les structures et fonctions membres 6 void main() { point a, b, TabPoint[3]; a.initialise (3, 7) ; a.affiche () ; b.x = 10; b.y = 20 ; b.affiche (); for(int i=0 ; i<3 ; i++){ TabPoint[i].initialise(i, i+4); TabPoint[i].affiche(); SOLUTION Affiche2(a, b); Programme 1.2. Je suis en 3 7 Je suis en Je suis en 0 4 Je suis en 1 5 Je suis en Je suis dans Affiche2... Je suis en 3 7 Je suis en Rqs Dans le cas des structures, un appel tel que a.initialise (3,7) ; pourrait être remplacé par: a.x = 3 ; a.y = 7 ; Dans un programme, nous pouvons évidemment mélanger fonctions membres et fonctions non membres. Exercices 1.1. Ecrire un programme qui gère un ensemble de Personnes (Nmax=10). Chaque Personne aura une structure avec un identifiant Id de type entier et un nom de type string dont la déclaration est: struct Personne { int Id; string nom; ; Ce programme doit gérer en boucle le menu suivant : 1 : Saisie et Affichage 2 : Ajouter au (début, milieu ou fin) et Affichage 3 : Supprimer le début et Affichage 4 : Tri selon NOM et Affichage 5 : Tri selon Id et Affichage 6 : Quitter Le menu sera affiché via une fonction, les choix seront traités via l instruction case. Votre programme utilisera une série de fonctions permettant de séparer les tâches Transformez l exercice précédent en utilisant dans la structure deux fonctions membres saisie() et affichage(). Apporter les modifications nécessaires à la structure, aux fonctions et au programme.

10 Chap 2 : Les listes simplement chaînées 2.1. Généralités Jusqu'à présent, nous n'avons travaillé qu'avec des structures de données statiques, dont l'espace mémoire occupé pouvait être défini avant l'exécution. Dans le cas d une déclaration d un tableau de structure par la syntaxe: struct Etudiant Tab[100] ; Cette déclaration permet de réserver automatiquement une zone mémoire d une longueur de 100 éléments de type Etudiant. Les cellules du tableau sont alors accessibles par Tab[0] à Tab[99]. Cependant, le problème réside dans le fait que la déclaration du tableau avec une dimension constante fige le nombre d éléments de ce tableau. Autrement dit, même si un programme n a besoin que de 20 éléments, on réservera malgré tout 100 cellules de type Etudiant. Comme nous l avons déjà vu en 1 ère Bachelier, nous pouvons remédier à cela en utilisant les pointeurs. Les instructions deviennent dans ce cas-ci : struct Etudiant *Tab; Pour pouvoir stocker en mémoire une valeur de type Etudiant, il faut donc explicitement demander une adresse disponible en utilisant le mot réservé new et la libérer avec delete. L allocation dynamique de la mémoire correspondant au nombre de cellules est maintenant au gré de l utilisateur. On peut, par exemple, lui demander d introduire un nombre N, puis nous réservons l espace mémoire strictement nécessaire. cout<< " Dimension du Tableau N : " ; cin >> N; // Allocation mémoire : new[] Tab = new Etudiant[N]; // Restituer la mémoire : delete[] delete[] Tab; Supposons qu à un moment donné dans le programme même, nous n ayons plus besoin que de (N-5) éléments. La logique, comme nous désirons optimiser la gestion de la mémoire, est de libérer la place de mémoire pour 5 cellules. Mais cela ne peut se faire ni automatiquement ni directement. Donc cela reste bien sûr limitatif. En effet, cela ne permet pas d'exploiter les structures tels que les listes chaînées, les piles, les arbres, structures fondamentales pour de nombreux algorithmes Listes Simplement chaînées Une liste chaînée est une séquence d'objets dynamiques dont chacun contient une indication explicite vers l'élément suivant. Une liste est faite de cellules. Chaque cellule contient un élément de la liste et l'adresse de l'élément suivant (structure de même type).

11 Chap 2 : Les listes simplement chaînées 8 Considérons donc la définition d'une liste simplement chaînée de structures contenant des strings. "Etud1" "Etud2" "Etud3" "Etud4" NULL Chaque cellule de la liste chaînée peut être définie comme une structure: struct Etudiant { string Nom; struct Etudiant *next; ; // Etudiant suivant Chaque cellule comporte donc une zone mémoire pour stocker son contenu (ici string Nom), ainsi qu'une zone mémoire pour stocker un pointeur vers la cellule suivante (c'est-à-dire l'adresse de la cellule suivante). Pour pouvoir travailler avec une liste simplement chaînée, il faut connaître l'adresse de sa première cellule. Nous définirons donc un pointeur: struct Etudiant *debut; Si les tableaux permettent un accès direct aux éléments, les listes chaînées en sont dépourvues. La définition et la nature même de la liste chaînée font apparaître que l on ne peut parcourir intégralement la liste qu en partant du premier élément et en visitant les éléments l un après l autre. En contrepartie nous gagnons en souplesse lorsqu il s agit de modifier la liste. Des opérations telles que : ajout, suppression d un élément à une position quelconque dans la liste, la suppression avec libération de mémoire d un nombre quelconque d éléments consécutifs, Voici un programme simple mais complet, dans lequel nous traitons un certain nombre d opérations sur la liste. Par exemple : l'insertion d'une nouvelle cellule en début de liste, le parcours de la liste pour l affichage, l effacement d'une cellule, la libération de la mémoire. #include <iostream> #include <string> using namespace std ; typedef struct Etudiant{ string Nom; struct Etudiant *next; // le lien : pointeur sur la cellule suivante liste; //insérer un nouvel élément en tête de liste et retourner un pointeur sur la liste. liste *insere_en_tete(string x, liste *lis ) { liste *c; c = new liste ; // créer une cellule if (c!=null){ c Nom=x; // assignation de x c next=lis; // assignation de suivant: chaîner avec la première cellule de la liste lis=c; return (lis); // chaînage: faire pointer la tête de liste vers la nouvelle cellule.

12 Chap 2 : Les listes simplement chaînées 9 void parcours (liste *lis) { liste *p; p = lis; cout << "Affichage : "<< endl; while ( p!= NULL) { cout << p Nom << endl; p = p next; cout <<endl<<endl; void liberation (liste *lis) { liste *p; p = lis; while ( p!= NULL) { lis=lis next; delete p; p = lis; void main() { int i, n; string Name; liste *debut; debut=null; // si p=null, donc fin de liste // liste vide cout << "nombre d'elements N: " ; cin >> n; // cout << "\n Creer une liste avec insertion en tete de liste + affichage \n"; for(i=1; i<=n; i++){ cout << "\n Nom "<< i << " : "; cin >> Name; debut=insere_en_tete(name, debut); parcours(debut); // Affichage // cout << "Inserer une nouvelle cellule apres la cellule debut " << endl; liste *p; p = new liste; p Nom = "Nouveau"; p next = debut next; debut next = p; parcours (debut); // cout << "Supprimer la 1ere cellule " << endl; liste *q; q=debut; debut=debut next; delete q; // mémoire dynamique n'est plus utilisée doit être libérée. parcours (debut); // // Libération cout << " Liberation de la memoire "; liberation (debut); Programme 2.1.

13 Chap 2 : Les listes simplement chaînées 10 nombre d'elements N: 3 Creer une liste avec insertion en tete de liste + affichage Nom 1 : premier Nom 2 : second Nom 3 : nom3 Affichage : nom3 second premier S O L U T I N Inserer une nouvelle cellule apres la cellule debut Affichage : nom3 Nouveau second premier Supprimer la 1ere cellule Affichage : Nouveau second premier Liberation de la memoire Exercices 2.1. Transformer l exercice 1.2. en remplaçant le tableau statique de structures Personne par une liste simplement chaînée.

14 Chap 2 : Les listes simplement chaînées 2.2. Parcours Vita 11 Ecrire un programme permettant de manipuler plusieurs listes dont le nombre est NL< Nmax=15. Il s agit d un Parcours Vita avec NL activités et un nombre de participants NP<Nmax. Les informations caractérisant chaque participant dans la liste sont les suivantes: Nom : chaîne de caractères Code : un caractère (A, B, ) Créer la (les) structure(s) nécessaire(s) à ce problème. Les fonctions Saisie(..) et Affichage(..) pour chaque élément (participant) sont déclarées dans la structure participant. Ce programme doit gérer en boucle le menu suivant : 1- SaisieL Liste1 et Affichage 2- Liste1 TO Liste2 et Affichage 3- Parcours et Affichage 4- Fin 1- Saisie Liste1 et Affichage: Est constitué au moins de deux fonctions : SaisieL (.) ; Dans cette fonction on demandera et on testera le nombre de participants (NP) à saisir et on effectuera la saisie des participants dans une liste par insertion en tête. Par exemple si NP=4 et l utilisateur introduit au clavier : (NomD D) puis (NomC C) puis (NB B) et enfin (NA A) La liste est : Affichage(.) ; (NA A) --- (NB B) --- (NomC C) --- (NomD D) 2- Liste1 Liste2 et Affichage: Ici, comme si les participants sautent, un par un, de la poutre1 (Liste1) à la poutre2 (Liste2). On applique (FIFO), c'est-àdire, on retire d abord le D de Liste1, on insère D dans Liste2 et on affiche liste1 et liste2. Liste1 : (NA A) --- (NB B) --- (NomC C) Liste2 : (NomD D) Puis on transfert (NomC C) de Liste1 vers Liste2. Ce dernier sera inséré dans Liste2 après (NomD D). Liste1 : (NA A) --- (NB B) Liste2 : (NomD D) --- (NomC C) Tant que liste1 n est pas vide, on continue. A la fin on aura l affichage suivant : Liste1 : Vide Liste2 : (NomD D) --- (NomC C) --- (NB B) ----(NA A) Attention : Ici on affiche l état des deux listes chaque fois qu un participant passe de la liste1 à la liste2. Il faut soigner tous les affichages afin de bien suivre et comprendre les différentes séquences. 3- Parcours et Affichage: Ici on demandera à l utilisateur le nombre NL et on y fera traverser les NP participants comme le montre la figure générale (début). On affiche toutes les listes chaque fois que toute l équipe passe d une liste à l autre. Si par exemple NL=3 on affichera: Liste1 : (NA A) --- (NB B) --- (NomC C) --- (NomD D) Liste2 : Vide Liste3 : Vide Liste1 : Vide Liste2 : (NomD D) --- (NomC C) --- (NB B) ----(NA A) Liste3 : Vide Liste1 : Vide Liste2 : Vide Liste3 : (NA A) --- (NB B) --- (NomC C) --- (NomD D) RQs : Utilisez les règles de bonnes pratiques étudiées durant les travaux pratiques telles que l indentation syntaxique, la programmation modulaire, libérer la mémoire d un élément supprimé!!

15 Chap3 : Les Classes Le but de ce chapitre est d introduire les concepts de base des objets. Ainsi, les termes de "programmation (orientée) objets", de classe, d'objet, de méthode, d encapsulation et type de membre (publique, privé) vont être définis. Ce chapitre n a pas la prétention d expliquer en détail ce type de conception, mais se propose d en introduire les idées maîtresses en préambule à l étude du langage C++. Afin d illustrer par la programmation ces concepts, ce chapitre est agrémenté de nombreux programmes permettant à l étudiant d assimiler les principales notions et de comprendre quelques subtilités de cette matière. Pour plus de précisions, le lecteur pourra se reporter aux références. Des notions comme l'héritage, le polymorphisme, seront abordées dans d autres chapitres de ce syllabus Classes et objets Une classe définit un regroupement de données et de fonctions ou méthodes. D'un point de vue syntaxique, une classe ressemble beaucoup à la définition d une structure, il suffit de remplacer le mot clé struct par le mot réservé class; préciser quels sont les membres publics (fonctions ou données) et les membres privés en utilisant les mots clés public et private. struct Etudiant { int Id; string Nom; void Saisie(); void Affiche(); ; Class Etudiant { private : // Cachées aux fonctions externes int Id; string Nom; // Accessibles depuis l'extérieur de la classe void Saisie(); void Affiche(); ; La déclaration d une classe commence par le mot-clé class suivi du nom de la classe et se termine par le point-virgule obligatoire. Le nom de la classe dans cet exemple est Etudiant. On appelle objet, une donnée d'un type class, c est une instanciation d une classe. Class Etudiant Etud1 ; // Etudiant est une classe, Etud1 est une instance d un objet. fonction membre ou méthode, un membre d'une classe qui est une fonction (Saisie), donnée membre, un membre qui est une variable (Id et Nom). Le C++ introduit des concepts de programmation orientée objet. Un des concepts majeurs est l'encapsulation des données.

16 Chap3 : Les Classes Concept d encapsulation Dans la classe Etudiant, toutes les fonctions membres sont désignées comme public et toutes les données membres comme private; les premières étant accessibles depuis l extérieur de la classe, les secondes l étant seulement depuis la classe. L'association de membres et fonctions au sein d'une classe, avec la possibilité de rendre privées certains d'entre eux, s'appelle l'encapsulation des données, un des concepts majeurs de la programmation orientée objet. Intérêt de la démarche: puisqu'elles ont été déclarées privées, les données membres Id et Nom ne peuvent être modifiées autrement que par un appel de la fonction Saisie(). En effet, l'encapsulation est un mécanisme consistant à rassembler les données et les méthodes au sein d'une classe en cachant l'implémentation de l'objet: cacher l'information contenue dans un objet et ne proposer que des méthodes ou des fonctions de manipulation de cet objet. Ainsi les propriétés contenues dans l'objet seront assurées/validées par les méthodes de l'objet et ne seront plus de la responsabilité de l'utilisateur extérieur. Les fonctions membres doivent pouvoir servir d'interface pour manipuler les données membres. L'utilisateur extérieur ne pourra pas modifier directement l'information et risquer de mettre en péril les propriétés comportementales de l'objet. L'encapsulation permet donc de garantir l'intégrité des données contenues dans l'objet. On place l'étiquette public devant les fonctions membres dédiées à la manipulation des données membres. En effet, si l'utilisateur de la classe ne peut pas modifier les données membres directement, il est obligé d'utiliser l'interface (les fonctions membres) pour les modifier, ce qui peut permettre au créateur de la classe d'effectuer des contrôles... Le C++ implémente l'encapsulation en permettant de déclarer les membres d'une classe avec le mot réservé public, private ou protected. Ainsi, lorsqu'un membre est déclaré : public, il sera accessible depuis n'importe quelle classe ou fonction. private, il sera uniquement accessible d'une part, depuis les fonctions qui sont membres de la classe et, d'autre part, depuis les fonctions autorisées explicitement par la classe (par l'intermédiaire du mot réservé friend (voir plus loin) ). protected, il aura les mêmes restrictions que s'il était déclaré private, mais il sera en revanche accessible par les classes héritières (voir plus loin). Dans la classe Etudiant, les membres nommés Id et Nom sont privés, tandis que les fonctions membres nommées Saisie() et Affiche() sont publiques. Les expressions public: et private: peuvent apparaître un nombre quelconque de fois dans une classe. Les membres déclarés après private: (resp. public:) sont privés (resp. publics) jusqu'à la fin de la classe, ou jusqu'à la rencontre d'une expression public: (resp. private:).

17 Chap3 : Les Classes 14 class XY { private : private :... ; Dans l exemple suivant, seule la fonction ft() pourra être appelée à partir de n importe quelle fonction du programme. Par contre il n est possible d accéder aux champs x et y que par l intermédiaire de la fonction membre public ft(). Ainsi l accès aux différents champs de la classe est contrôlé. class point { private : int x, y; void gt( ); // fonction membre privée void ft( ) ; // fonction membre public // champs membres privés de la classe ; Le C++ n'impose pas l'encapsulation des membres dans leurs classes. On pourrait donc déclarer tous les membres publics, mais en perdant une partie des bénéfices apportés par la programmation orientée objet. Il est de bon usage de déclarer toutes les données privées, ou au moins protégées, et de rendre publiques les méthodes agissant sur ces données. Ceci permet de cacher les détails de l'implémentation de la classe. Si l'on rend publics tous les membres d'une classe, on obtient l'équivalent d'une structure. Ainsi, ces deux déclarations définissent le même type point : struct point { int x, y; void gt( ); void ft( ); ; class point { int x, y; void gt( ); void ft( ); ; Dans une classe, tout ce qui n est pas déclaré public est privé par défaut. Ainsi, ces deux déclarations sont équivalentes : class point { private : int x, y; void gt( ); void ft( ); ; class point { int x, y; void gt( ); void ft( ); ;

18 Chap3 : Les Classes Création d'objets En C++, il existe deux façons de créer des objets, c'est-à-dire d'instancier une classe : de façon statique de façon dynamique La création statique d'objets consiste à créer un objet en lui affectant un nom, de la même façon qu'avec une variable : Nom_de_la_classe Nom_de_l_objet; Etudiant Etud1 ; // Etudiant est une classe, Etud1 est une instance de la classe Etudiant. Ainsi, l'objet est accessible grâce à son nom... La création dynamique d'objet est une création d'objet par le programme lui-même en fonction de ses «besoins» en objets. La gestion dynamique des objets se fait de la même manière que la gestion dynamique de la mémoire pour des variables simple (int, float, ) ou structures. C est la manipulation, comme nous l avons vu en 1 ère année Bachelier, des pointeurs en utilisant les opérateurs spécifiques : new, delete, new[] et delete[]. L opérateur new permet d'allouer de la mémoire, alors que l opérateur delete la restitue. La syntaxe de new est très simple, il suffit de faire suivre le mot clé new du type de la variable à allouer, et l'opérateur renvoie directement un pointeur sur cette variable avec le bon type. Par exemple, l'allocation d'un objet Etudiant se fait comme suit : Etudiant *Etud; Etud = new Etudiant; // pointeur vers la classe Etudiant // création de l'objet «dynamique» grâce au mot clé new L accès aux "membre public" se fait de la manière suivante : Etud Saisie(); ou (*Etud).Saisie(); Etud Affiche(); Etud Nom ; La syntaxe de delete est plus simple, puisqu'il suffit de faire suivre le mot clé delete du pointeur sur la zone mémoire à libérer : delete Etud; Les opérateurs new[] et delete[] sont utilisés pour allouer et restituer la mémoire pour les types tableaux. L'emploi de l'opérateur new[] nécessite de donner la taille du tableau à allouer. Ainsi, on pourra créer un tableau de 500 objets de la manière suivante : Etudiant *Tableau=new Etudiant[500]; et détruire ce tableau de la manière suivante : delete[] Tableau; Tout objet créé dynamiquement, c'est-à-dire avec le mot-clé new devra impérativement être détruit à la fin de son utilisation grâce au mot clé delete. Dans le cas contraire, une partie de la mémoire (celle utilisée par les objets créés dynamiquement) ne sera pas libérée à la fin de l'exécution du programme...

19 Chap3 : Les Classes Affectation d objets On a déjà vu que l on peut affecter à une structure la valeur d'une autre structure de même type. Ainsi, avec les déclarations suivantes : struct point { int x, y; ; struct point A, B; Nous pouvons écrire sans problème : A = B ; Cette instruction recopie l'ensemble des valeurs des champs de B dans ceux de A. Elle joue le même rôle que : A.x = B.x ; A.y = B.y ; En C++, cette possibilité d affectation globale s'étend aux objets de même type. Elle correspond à une recopie des valeurs des membres données, que ceux-ci soient publics ou non. Ainsi, avec ces déclarations (notez qu'ici nous avons prévu, artificiellement, x privé et y public) : class point { int x ; int y ; ; point A, B ; L instruction : B = A ; provoquera la recopie des valeurs des membres x et y de A dans les membres correspondants de B. Contrairement à ce qui a été dit pour les structures, il n'est plus possible ici de remplacer cette instruction par : B.x = A.x ; B.y = A.y ; En effet, si la deuxième affectation est légale, puisque ici y est public, la première ne l'est pas, car x est privé. Notez bien que l'affectation B = A est toujours légale, quel que soit le statut (public ou privé) des membres données. On peut considérer qu'elle ne viole pas le principe d'encapsulation, dans la mesure où les données privées de B (c'est-à-dire les copies de celles de A) restent toujours inaccessibles de manière directe Déclaration d une fonction membre En ce qui concerne la définition des fonctions membres d'une classe, elle se fait de la même manière que celle des fonctions membres d'une structure (qu'il s'agisse de fonctions publiques ou privées). Il existe deux façons de définir ces fonctions membres, en définissant : le prototype et le corps de la fonction à l'intérieur de la classe en une opération ; le prototype de la fonction à l'intérieur de la classe et le corps de la fonction à l'extérieur.

20 Chap3 : Les Classes 17 La seconde solution est généralement celle la plus utilisée. Ainsi, puisque l'on définit la fonction membre à l'extérieur de sa classe, il est nécessaire de préciser à quelle classe cette dernière fait partie. On utilise pour cela l'opérateur de résolution de portée, noté ::. Il suffit ainsi de faire précéder le nom de la fonction par ::, suivi du nom de la classe pour lever toute ambiguïté (deux classes peuvent avoir des fonctions membres différentes portant le même nom...). Le programme 3.1 montre ce que devient le programme 1.1 lorsque l'on remplace la structure Etudiant par la classe Etudiant. Ce programme permet aussi d illustrer un exemple de définitions de fonctions à l intérieur et à l extérieur de la classe. La fonction Affiche() est définie à l intérieur de la classe Etudiant, tandis que la déclaration de la fonction Saisie() est à l intérieur et sa définition est à l extérieur de la classe. #include <iostream> using namespace std ; class Etudiant { int Id; string Nom; public: void Saisie() ; ; void Affiche(){ cout << "identifiant ="<< Id << endl; cout << "Son nom : "<< Nom << endl; // déclaration des membres privés // Définition de la fonction membre à l extérieur de la classe void Etudiant::Saisie() { cout << "donnez un identifiant"<< endl; cin >> Id; cout << "donnez un nom"<< endl; cin >> Nom; // Définir une fonction membre dans la classe void main(){ Etudiant Etud1, Etud2; Etud1.Saisie(); Etud1.Affiche(); // 2 objets de la classe Etudiant Etud2.Saisie(); Etud2.Affiche(); Programme 3.1. Dans le programme 2.1, Etud1 et Etud2 sont déclarés comme objets de la classe Etudiant. C est pourquoi ils possèdent leurs propres données membres Id et Nom, et la capacité d appeler les deux fonctions membres de la classe : Saisie() et Affiche(). Il faut noter qu une fonction comme Saisie()est appelée en préfixant son nom du nom de son propriétaire : Etud1.Saisie(). Une fonction membre peut être définie dans la classe (Affiche( ) ou à l extérieur (Saisie() ). Dans la plupart des cas, il est préférable de définir ces fonctions hors de la déclaration de la classe à l aide de l opérateur de résolution de portée (Etudiant::Saisie()). Ceci permet

21 Chap3 : Les Classes 18 de séparer physiquement les déclarations de fonctions de leurs définitions et donc une meilleure lisibilité du programme. Rq Il faut remarquer que les données membres privés " x et y " sont accessibles dans les fonctions membres (Saisie()et Affiche()) sans quelles passent comme arguments de ces fonctions. A titre d exemple, voici ce que devient le programme 1.2 lorsque l'on remplace la structure point par la classe point : #include <iostream> using namespace std ; class point { private : int x, y; // Déclaration des fonctions membres (méthodes) void initialise(int, int) ; void affiche() ; ; void point::initialise (int abs, int ord) { x = abs ; y = ord ; void point::affiche () { cout << "Je suis en " << x << " " << y << "\n" ; void main() { point a, TabPoint[3]; a.initialise (3, 7) ; a.affiche () ; for(int i=0 ; i<3 ; i++){ TabPoint[i].initialise(i, i+4); TabPoint[i].affiche(); SOLUTION Programme 3.2. Je suis en 3 7 Je suis en 0 4 Je suis en 1 5 Je suis en 2 6 Rqs 1. Si pour les structures (programme 1.2) un appel tel que a.initialise(3,7) ; pouvait être remplacé par : a.x = 3 ; a.y = 7 ; Cela n est plus possible pour les classes. En effet, comme les données membres de point sont privées, on ne peut pas y accéder directement. Il faut absolument passer par une fonction membre publique. Une tentative d'utilisation directe comme a.x = 3; a.y = 7; au sein de la fonction main, conduirait à une erreur de compilation dont le genre de message ressemblerait à : error C2248: 'x' : cannot access private member declared in class 'point', see declaration of 'x' error C2248: 'y' : cannot access private member declared in class 'point', see declaration of 'y' 2. Dans l exemple du Programme 2.2, les deux fonctions membres sont publiques. Il est tout à fait possible d'en rendre l une ou l autre, voire les deux privées. Dans ce cas, de telles fonctions ne seront plus accessibles de l "extérieur" de la classe. Elles ne pourront être appelées que par d'autres fonctions membres.

22 Chap3 : Les Classes 19 Voici encore deux exemples pour illustrer le fonctionnement et l accès aux membres privés : #include <iostream> using namespace std; class CRec { private: int Long, Larg; public: void initialise(int Lo, int La){ Long = Lo; Larg = La; int Surf() { return (Long*Larg); ; void main() { CRec Rc1, Rc2, Rc3; Rc1.initialise(10,20) ; cout <<"\n Surface rectangle 1 = "<< Rc1.Surf(); cout <<"\n Surface rectangle 2 = "<< Rc2.Surf(); // Rc3.Long = 30; // Rc3.Larg = 24; // cout <<"\n Surface rectangle 3 = "<< Rc3.Surf(); Programme 3.3. L ajout des lignes 10 et 11 provoquerait des erreurs à la compilation. En effet, comme Long et Larg sont des membres privés de la classe, on ne peut y accéder de l extérieur qu à travers les fonctions publiques de la classe. Donc si l on désire modifier ces valeurs pour Rc3, il faut faire appel à la fonction initialise(). L exemple suivant attire l attention sur le mode d utilisation des membres privés et l accès à un objet lorsque nous avons plus d une classe. class A { private : int a ; void fonction_a(); ; class B { private : int b ; void fonction_b(); ; void A:: fonction_a(){ A a0; B b0; a=5; //OK: a et fonction_a() dans la classe A a0.a = 1 //OK : a0 est un objet de la classe A b0.b = 3 // OK : b est private dans B, donc pas accessible // dans une fonction de A. Le principe d encapsulation interdit à une fonction membre d une classe d accéder à des données privées d une autre classe. Nous verrons plus loin comment contourner cela sans perdre le bénéfice de la protection des objets.

23 Chap3 : Les Classes Notions de constructeur et de destructeur Dans la version actuelle des programmes 2.2 et 2.3, les données membres x, y (class point) et Long, Larg (class CRec) sont initialisées par l'intermédiaire de la fonction membre initialise(). Dans une classe, cette initialisation peut être simplifiée. En effet, lors de la création d'un objet, une fonction membre particulière est exécutée, si elle existe. Cette fonction est appelée constructeur. Le C++ offre un mécanisme très performant pour traiter ces problèmes : le constructeur. Il s'agit d'une fonction membre d initialisation (définie comme les autres fonctions membres) qui sera appelée et exécutée automatiquement à chaque création d'un objet. Ceci a pour effet de simplifier la programmation et assurer l initialisation des données membres. Parmi les méthodes d'un objet se distinguent deux types de méthodes bien particulières et remplissant un rôle précis dans sa gestion : les constructeurs et les destructeurs. Le constructeur : porte le nom de sa classe, définit l'initialisation d'une instance, notamment en initialisant ses données membres, est appelé implicitement à toute création d'instance, ne peut retourner aucune valeur, (fonction membre non typée même pas void ), peut admettre des arguments qui sont en fait les valeurs d initialisation des différents champs de la variable. La définition d'un constructeur n'est pas obligatoire lorsqu'il n'est pas nécessaire. Un objet qui n a pas de constructeur explicite, le compilateur se charge de créer de manière statique les liens entre champs et méthodes. Un objet peut avoir autant de constructeurs que l on veut (tant qu ils diffèrent par leur nombre et types d arguments), ce qui est très intéressant pour initialiser les variables avec différents types. Dans ce cas c est l utilisateur qui décidera du constructeur à appeler. De même, le destructeur est une fonction membre appelée automatiquement au moment de la destruction de l'objet, il : est une fonction membre non typée et sans paramètre, porte le nom de sa classe précédé d'un tilde (~), n'a pas de type de retour (même pas void), définit la "désinitialisation" d'une instance, il se charge de détruire l'instance de l'objet, est appelé implicitement à toute disparition d'instance. Attention, il n y a qu un un seul destructeur par classe!

24 Chap3 : Les Classes Constructeurs par défaut Constructeurs par défaut sans arguments Le premier type de constructeur par défaut est de type : point::point(). C est un constructeur qui peut être appelé sans paramètre. Son rôle est de créer une instance "non initialisée" quand aucun autre constructeur fourni n est applicable. Donc il est appelé chaque fois qu'un objet est créé sans qu'il y ait appel explicite d'un constructeur. Comme les autres fonctions membres, les constructeurs peuvent être déclarés dans la classe et définis soit à l intérieur ou ailleurs. Le programme ci-dessous est un programme simple mettant en évidence les moments où sont appelés respectivement le constructeur et le destructeur d'une classe. Pour garder une trace de leur appel, nous y affichons un message. #include <iostream> #include <string> using namespace std ; class Etudiant { private : int Id ; string Nom ; public: Etudiant() { // Constructeur cout << "Dans constructeur"<<endl; Id = -1 ; Nom = "Vide"; ~Etudiant() { // Destructeur cout << "Dans destructeur"; void Affiche(){ cout << " Identifiant ="<< Id << endl; cout << " Son nom : "<< Nom << endl; ; void main(){ Etudiant Etud; Etud.Affiche(); // Création d un objet Etud Programme 3.4. Ce programme montre comment on peut définir les fonctions membres, y compris constructeur et destructeur, à l'intérieur de la définition de la classe. Son exécution affichera à l écran : Dans constructeur Identifiant =-1 Son nom : Vide Dans destructeur En effet, lors de la création de l objet Etud de la classe Etudiant, le constructeur est appelé, d où le commentaire "Dans constructeur". Ensuite on rencontre la fonction Affiche() qui montre les valeurs d initialisation des données membres. Enfin, comme le

25 Chap3 : Les Classes 22 programme n a plus d instructions à exécuter, il détruit l objet avant de quitter la fonction main() en appelant le destructeur Constructeurs par paramètres Le constructeur peut posséder des paramètres. Pour illustrer le fonctionnement d un tel constructeur, le programme 3.2 peut être transformé comme suit : #include <iostream> using namespace std ; class point { private : int x, y; // Déclaration des fonctions membres (méthodes) point(int, int) ; // Constructeur: lors de la création d 1 objet point // cette fonction sera appelée void affiche() ; ; point::point (int abs, int ord) { x = abs ; y = ord ; void point::affiche () { cout << " Je suis en " << x << " " << y << "\n" ; void main() { point a(3,7); cout << "Objet a : " << endl; a.affiche() ; // création d'objet a et initialisation des données for(int i=0 ; i<3 ; i++){ point b(i, i+4); cout << "Objet b (" << i << ") : "<< endl; b.affiche(); cout << "Objet c : " << endl point c = point(5, 6); c.affiche() ; cout << "Objet *Pt: " << endl; point *Pt; Pt = new point(8, 9); Pt->affiche(); delete Pt; Solution Programme 3.5. Objet a : Je suis en 3 7 Objet b (0) : Je suis en 0 4 Objet b (1) : Je suis en 1 5 Objet b (2) : Je suis en 2 6 Objet c : Je suis en 5 6 Objet *Pt : Je suis en 8 9

26 Chap3 : Les Classes 23 Un constructeur est toujours appelé lorsqu'un objet est créé, soit explicitement, soit implicitement. Les appels explicites peuvent être écrits sous deux formes : point a(3, 4); // Création de l objet «a» + appel du constructeur avec des arguments 3 et 4 point c = point(5, 6); Dans le cas d'un constructeur avec un seul paramètre, on peut aussi adopter une forme qui appelle l'initialisation des variables de types primitifs : point e = 7; // équivaut à : point e = point(7) ; Un objet alloué dynamiquement est lui aussi toujours initialisé, au mois implicitement. Dans beaucoup de cas il peut, ou doit, être initialisé explicitement. Cela s'écrit : point *Pt; Pt = new point(8, 9); delete Pt; Voici deux autres exemples illustrant la définition du constructeur (initialiser, voire créer dynamiquement un objet) par paramètres et le destructeur. class CRec { public: int Long; int Larg; CRec(int Lo, int La){ Long = Lo; Larg = La; ~CRec() ; ; ~CRec()::CRec(){ Long = 0; Larg=0; class Etudiant { private : int Id ; char *Nom ; public: Etudiant (int id, string Name) { Id = id ; Nom = new char[name.size()+1]; ~ Etudiant() { // Destructeur if (Nom!=NULL) delete [] Nom ; ; Cependant, à partir du moment où un constructeur est défini, il doit pouvoir être appelé (automatiquement) lors de la création de l'objet. Dans le programme 2.5 ou dans les deux exemples, les constructeurs point et CRec ont besoin de deux arguments alors que Tab en a besoin d un. Ceux-ci doivent obligatoirement être fournis dans notre déclaration. Dans cet exemple : CRec R1(10, 20) ; Tab T(10) ; CRec R2 ; Tab T1, T2[10]; point Pt ; // Création d un objet R1, donc lancement du constructeur // R1.Long=10 etr1.larg=20 ; // Création d un objet T : donc réservation d un espace mémoire pour 10 entiers // Erreur // Erreur // Erreur les déclarations de R2, T1, T2[10] et Pt provoquent des erreurs à la compilation car il ne possèdent pas le nombre nécessaire d arguments. Ceci montre un exemple où il est nécessaire de fournir à la classe point un constructeur par défaut de type point::point(). La classe peut dès lors être déclarée comme suit:

27 Chap3 : Les Classes 24 class point { int x, y ; point () ; point (int, int) ; ~point() ; ; // déclaration des membres privés // déclaration des membres publics // constructeur // constructeur // destructeur Il ne reste qu à définir le destructeur et les différents constructeurs, par exemple : point::point() { x = 3 ; y = 4 ; //constructeur par défaut sans param point::point (int abs, int ord) { x = abs ; y = ord ; point :: ~point () { cout << "Dans destructeur au revoir \n" ; x=0; y = 0; Dans cette version, la classe point a deux constructeurs. Le premier n a pas de paramètres et initialise l objet déclaré à l aide des valeurs par défaut 3 et 4. Le deuxième a des paramètres que l utilisateur peut modifier au moment de la déclaration, mais pas de valeurs par défaut. Les deux constructeurs permettent d initialiser les objets dès leurs déclarations. point Pt(10, 20); // Création d un objet Pt, avec initialisation // Pt.x=10 et Pt.y=20 ; point T; // Création d un point T, donc lancement du // Constructeur par défaut T.x=3 et T.y=4 point T[5]; // produit 5 appels de point() point *pt = new point[10]; // produit 10 appels de point() Le programme suivant montre l utilisation du destructeur et des deux types de constructeurs. #include <iostream> using namespace std; class CRec { public: int Long, Larg; CRec (int Lo, int La){ ; cout << "In Constructeur Param"<< endl ; Long = Lo; Larg = La; CRec (){ cout << "Dans Constructeur 0000"<< endl ; ~CRec (){ cout << "Lancer Destructeur" << endl; int CalcSurf() { return (Long*Larg);

28 Chap3 : Les Classes 25 void main() { CRec Rc1(10,20), Rc2, Rc3; cout <<"\n Surface rectangle 1 = "<< Rc1.CalcSurf(); cout <<"\n Surface rectangle 2 = "<< Rc2.CalcSurf(); Rc3.Long = 30; Rc3.Larg = 24; cout <<"\n Surface rectangle 3 = "<< Rc3.CalcSurf()<< endl; Programme 3.6. Dans Constructeur Param Dans Constructeur 0000 Dans Constructeur 0000 Solution Surface rectangle 1 = 200 Surface rectangle 2 = 0 Surface rectangle 3 = 720 Lancer Destructeur Lancer Destructeur Lancer Destructeur Rq Il faut remarquer que dans ce programme, les données Long et Larg sont définies comme public dans la classe CRec. C est pour cette raison que les initialisations : Rc3.Long = 30; Rc3.Larg = 24; sont autorisées. Si la classe est déclarée comme ceci : class CRec { private: int Long, Larg; CRec (int Lo, int La){. les assignations suivantes: Rc3.Long = 30; Rc3.Larg = 24; provoqueraient des erreurs à la compilation, du genre : error C2248: 'Long' : cannot access private member declared in class 'CRec' error C2248: 'Larg' : cannot access private member declared in class 'CRec' Par souci de compréhension et pour mieux maîtriser l enclenchement du constructeur et du destructeur, voici comment pourrait être adapté le programme 2.5 afin de tracer les appels de ces fonctions:

29 Chap3 : Les Classes 26 #include <iostream> using namespace std ; class point { int x, y ; point (int abs, int ord){ x = abs ; y = ord ; cout << "++ Construction d'un point :" << x << " " << y << "\n" ; ~point(){ cout << "-- Destruction du point : " << x << " " << y << "\n" ; ; point a(1,1) ; // instanciation "Globale" d un objet de classe point void main(){ cout << "****** Debut main *****\n" ; point b(10,10) ; // un objet automatique de classe point point c(3,3) ; int i ; for (i=1 ; i<=3 ; i++) { cout << "** Boucle tour numero " << i << "\n" ; point b(i,2*i) ; // objets créés dans un bloc cout << "****** Fin main ******\n" ; Programme Construction d'un point : 1 1 Solution ****** Debut main ***** ++ Construction d'un point : Construction d'un point : 3 3 ** Boucle tour numero 1 ++ Construction d'un point : Destruction du point : 1 2 ** Boucle tour numero 2 ++ Construction d'un point : Destruction du point : 2 4 ** Boucle tour numero 3 ++ Construction d'un point : Destruction du point : 3 6 ****** Fin main ****** -- Destruction du point : Destruction du point : Destruction du point : 1 1 Nous demandons aux étudiants de bien comprendre cette solution. Une discussion à ce sujet sera abordée durant les séances d exercices. Nous traiterons aussi d autres exemples afin d illustrer au mieux la trace des appels des constructeurs et destructeurs.

30 Chap3 : Les Classes Constructeurs par défaut et par paramètres Le constructeur par défaut est un constructeur qui peut être appelé sans paramètres : ou bien il n'en a pas, ou bien tous ses paramètres ont des valeurs par défaut. Il joue un rôle remarquable, car il est appelé chaque fois qu'un objet est créé sans qu'il y ait appel explicite d'un constructeur. Voici un exemple de constructeur par défaut pour la classe CRec. Il possède des paramètres avec des valeurs de défaut pour l initialisation. CRec :: CRec (int Lo = 0, int La = 0){ Long = Lo; Larg = La; Dans ce cas, la déclaration d un objet peut se faire avec deux, un ou aucun argument. L exemple suivant illustre des créations valides pour des objets de type CRec : CRec X; // OK Equiv : Z.Long=0 ; Z.Larg = 0 CRec Y(1); // OK Equiv : Z.Long=1 ; Z.Larg = 0 CRec Z(1,2); // OK : Equiv : Z.Long=1 ; Z.Larg = 2 En effet, de la même façon qu'une fonction, un constructeur peut être surchargé. Dans l'exemple suivant, un objet de type CRec, peut être créé en passant 0, 1 ou 2 arguments. Si aucun argument n'est passé, Long et Larg sont initialisés à la valeur 0. Si un argument est passé Y(1), cela correspondra à Long=1 et Larg=0. Si 2 arguments sont passés, ils sont utilisés pour initialiser les données membres Constructeur de copie Le constructeur de copie (ou de recopie) est spécialisé dans la création et l initialisation d un objet à partir d un autre objet pris comme modèle. Il est donc appelé lorsqu on doit créer une instance d un objet qui est la copie d un autre objet. Toute classe dispose d'un constructeur de copie par défaut généré automatiquement par le compilateur, dont le seul but est de copier les champs de l'objet à copier un à un dans les champs de l'objet à instancier. Toutefois, ce constructeur par défaut ne suffira pas toujours, et le programmeur devra parfois en fournir un explicitement. Ce sera notamment le cas lorsque certaines données des objets auront été allouées dynamiquement. Le constructeur de copie sert à créer un objet identique à l objet reçu en paramètre. C est un constructeur dont le premier paramètre est de type «C &» (référence sur un C) ou «const C &» (référence sur un C constant) et dont les autres paramètres, s'ils existent, ont des valeurs par défaut. La syntaxe habituelle d un constructeur de copie est la suivante : point::point(const point& Pt) point(const point& Pt) // Pt est l'objet à copier // Si la définition est dans la classe

31 Chap3 : Les Classes 28 Rqs Les attributs de l objet passé en paramètre sont recopiés dans les attributs de l objet à créer, en prenant garde d allouer un nouvel espace mémoire pour stocker le nom de l objet (Pt, RC1, ) ; Le constructeur de copie est aussi appelé lorsqu une fonction retourne un objet (attention: le constructeur de copie n est pas appelé lorsqu une fonction retourne une référence à un objet); S il existe un constructeur au moins, toute instance qui naît est soit construite par un constructeur appelé implicitement, soit initialisée par une instance déjà construite. Pour illustrer l utilisation de constructeur par copie, nous reprenons la classe Etudiant qui nous permettra par la même occasion de manipuler les pointeurs. Dans ce programme, nous avons effectué quelques modifications afin d enrichir cette classe. #include <iostream> #include <string> using namespace std ; class Etudiant { private : int Id ; char *Nom ; public: Etudiant (int id, string Name) { cout << Constructeur \n ; Id = id ; Nom = new char[name.size()+1]; for (int i=0; i< Name.size(); i++) Nom[i]=Name[i]; Nom[i]='\0'; Etudiant(const Etudiant& ET) { cout << Constructeur de copie\n ; if (ET.Nom) { Nom = new char[strlen(et.nom) + 1]; strcpy(nom, ET.Nom); Id = ET.Id; else{ Nom = 0; Id = 0; ~ Etudiant() { // Destructeur if (Nom!=NULL) delete [] Nom ; // Constructeur // pour fin de chaîne de caractères ; void Affiche(){ cout << " cout << " Identifiant ="<< Id << endl; Son nom : "<< Nom << endl; void main(){ string Name; cout << " Name...: "; cin >> Name; Etudiant E1(100, Name);

32 Chap3 : Les Classes 29 E1.Affiche(); Etudiant E2(E1); // copie de E1 dans E2 (1) E2.Affiche(); Etudiant E3=E1; // copie de E1 dans E3 (2) E3.Affiche(); Programme 3.8. Solution Name...: Ghandi Constructeur Identifiant =100 Son nom : Ghandi Constructeur de copie Identifiant =100 Son nom : Ghandi Constructeur de copie Identifiant =100 Son nom : Ghandi Comme le montre la solution, dans les deux exemples (1) et (2), c'est le constructeur de copie qui est appelé et pas le constructeur normal Listes d initialisation des constructeurs La plupart des constructeurs ne font qu initialiser les données membres de l objet. Le C++ propose un dispositif appelé liste d initialisation. L exemple suivant illustre comment on peut réécrire les constructeurs des différents exemples à l aide d une liste d initialisation : Etudiant() { Id = -1 ; Nom = "Vide"; point (int abs, int ord){ x = abs ; y = ord ; CRec (int Lo = 0, int La = 0){ Long = Lo; Larg = La; Etudiant() : Id (-1), Nom ("Vide") { point (int abs, int ord) : x (abs), y (ord) { CRec (int Lo = 0, int La = 0) : Long (Lo), Larg (La) { Les déclarations d affectation se trouvant dans les corps des fonctions sont supprimées. Leur action est gérée par la liste d initialisation en gras dans les exemples. Remarquez que la liste commence par deux points et précède le corps des fonctions qui sont maintenant vides.

33 Chap3 : Les Classes Affectation d un objet par un autre de la même classe Une partie sur l affectation d objets a déjà été traitée dans le paragraphe 3.4.(Affectation d objets) de ce chapitre. Cependant, maintenant que les constructeurs ont été vus, voici un programme véhiculant un complément d informations sur le sujet. #include <iostream> using namespace std; class CRec { int Long, Larg; // membres privés public: CRec (int Lo, int La){ cout << "\n Dans Constructeur Param"<< endl ; Long = Lo; Larg = La; CRec (){ cout << "\n Dans Constructeur 0000"<< endl ; int CalcSurf() { return (Long*Larg); ; void main() { CRec Rc1(10,20), Rc2; int Surface = 0; Rc2 = Rc1; Surface = Rc1.CalcSurf(); cout << "\n Surface rectangle 1 = " << Surface; cout << "\n Surface rectangle 2 = " << Rc2.CalcSurf(); Rc1=CRec(5,15); cout << "\n Surface rectangle 1 = " << Rc1.CalcSurf(); CRec Rc3=Rc1; // initialisation CRec Rc4(Rc1); // idem (syntaxe équivalente) cout << "\n Surface rectangle 3 = " << Rc3.CalcSurf(); cout << "\n Surface rectangle 4 = " << Rc4.CalcSurf(); Programme 3.9. Dans Constructeur Param Dans Constructeur 0000 Solution Surface rectangle 1 = 200 Surface rectangle 2 = 200 Dans Constructeur Param Surface rectangle 1 = 75 Surface rectangle 3 = 75 Surface rectangle 4 = 75 Remarquez que dans cette solution, le constructeur ne s est pas enclenché pour : CRec Rc3=Rc1; Rq CRec Rc4(Rc1);

34 Chap3 : Les Classes Tableau d objets Un tableau d objets est défini et manipulé de la même façon qu un tableau contenant des éléments issus des types fondamentaux. Lors de la création d un tableau d objets, un constructeur est appelé pour chaque élément du tableau (implicitement, c est celui sans paramètre). Lorsque la classe ne définit pas un tel constructeur, il faut nécessairement initialiser chaque élément en indiquant le constructeur à appeler. Si nous considérons la classe CRec définit comme: class CRec { int Long, Larg; public: CRec (int Lo, int La){ Long = Lo; Larg = La; int CalcSurf() { return (Long*Larg); ; La déclaration d un tableau de trois objets de type CRec par: CRec Tab[3] ; conduira à une erreur de compilation. En effet, dans ce cas le constructeur sans paramètre sera appelé successivement pour chacun des éléments. Or, dans cet exemple la classe n en possède pas. Dans ce cas, il faut éventuellement déclarer le tableau comme suit : CRec Tab[3] = { CRec(1,2),CRec(5,7),CRec(3,9) ); Une autre solution est d ajouter un constructeur par défaut sans paramètre ou encore remplacer le constructeur de cette classe par un constructeur par défaut et par paramètres. CRec (int Lo=0, int La = 0){ Long = Lo; Larg = La; // constructeur (0, 1 ou 2 arguments) Dans ce cas la déclaration CRec Tab[3]; permet d initialiser à zéro Long et Larg de chaque élément du tableau. Voici un programme illustrant la construction et l initialisation d un tableau d objets. #include <iostream> using namespace std ; class CRec { int Long, Larg; public: CRec (int Lo=0, int La=0){ Long = Lo; Larg = La; cout <<"++ Constructeur ---> : " << Long << " et "<< Larg<<"\n"; ~CRec () { cout <<"-- Destructeur : --->: " << Long << " et "<< Larg<<"\n"; ; void main() { int n = 2 ; CRec Tab[5] = { CRec(3,4), 9, n, 5*n+2 ; (1) cout << "*** fin du programme ***\n" ; Programme 3.10.

35 Chap3 : Les Classes 32 Solution ++ Constructeur ---> : 3 et 4 ++ Constructeur ---> : 9 et 0 ++ Constructeur ---> : 2 et 0 ++ Constructeur ---> : 12 et 0 ++ Constructeur ---> : 0 et 0 *** fin du programme *** -- Destructeur : --->: 0 et 0 -- Destructeur : --->: 12 et 0 -- Destructeur : --->: 2 et 0 -- Destructeur : --->: 9 et 0 -- Destructeur : --->: 3 et 4 On peut remarquer que la liste d initialisation (1) peut comporter moins de valeurs que le tableau n a d éléments. Chaque fois qu un argument d initialisation est manquant, il est remplacé par la valeur par défaut (zéro dans cet exemple) Surcharge des opérateurs Avec les outils du langage étudiés jusqu'à présent nous pouvons définir des nouvelles classes, créer des objets de ces classes et les manipuler presque comme les objets des types primitifs. Néanmoins, avec des objets des types primitifs on peut écrire int i, j; if (i == j) {.. Autrement dit, on peut utiliser les opérateurs arithmétiques et logiques qui sont prédéfinis par le langage. C++ offre au programmeur la possibilité de définir la plupart des opérateurs pour une classe quelconque. Pour illustrer cela, reprenons un programme ou une partie de programme facile comme le programme 2.4. On désire savoir si 2 objets de la classe point sont identiques. Pour répondre à cette question on peut ajouter une fonction membre qui permet de comparer 2 objets de cette classe. #include <iostream> #include <string> using namespace std ; class point { private : int x, y; // Déclaration des fonctions membres (méthodes) point(int, int) ; // Constructeur void affiche(string ) ; int EstEgal(point ) ; ; point::point (int abs, int ord) { x = abs ; y = ord ; void point::affiche (string T) { cout << T << "Je suis en " << x << " " << y << "\n" ;

36 Chap3 : Les Classes 33 int point::estegal (point Pt){ if ( (x==pt.x) && (y==pt.y) ) return 1 ; else return 0; void main() { point a(3,7); // création d'objet a et initialisation des données a.affiche("objet a : ") ; point b(4, 4); b.affiche("objet b : ") ; if (a.estegal(b)==1) cout << " Oui EGALITE "<< endl; else cout << " Non EGALITE "<< endl; point c(3, 7); c.affiche("objet c : ") ; if (a.estegal(c)==1) cout << " Oui EGALITE "<< endl; else cout << " Pas d EGALITE "<< endl; Programme Solution Objet a : Je suis en 3 7 Objet b : Je suis en 4 4 Non EGALITE Objet c : Je suis en 3 7 Oui EGALITE Mais il est souhaitable de pouvoir comparer ces 2 objets de la même façon que l'on compare 2 objets d'un type primitif. if ( a == b). else. Nous allons donc redéfinir l'opérateur d'égalité "==" pour les objets de la classe point. int point::operator==(point Pt) { if ( (x==pt.x) && (y==pt.y) ) return 1 ; else return 0; Pour comparer 2 objets de la classe point, on peut utiliser la fonction operator== à la place de la fonction membre EstEgal : a.operator==(b) Mais on peut aussi l'utiliser comme dans le cas d'un objet de type primitif : if (a == b). Les opérateurs qui peuvent être surchargés sont : + - * / % ^ & ~! ' = < > <= << >> ==!= && += -= /= %= ^= &= = *= <<= >>= [] () -> ->* new delete La surcharge des opérateurs les plus utilisés vous sera demandée comme exercices.

37 Chap3 : Les Classes 34 Exercices 3.1. Transformez l exercice 1.2. en remplaçant la structure Personne par une classe Personne Transformez l exercice 2.2. «Parcours Vita» en remplaçant la structure par une classe Ecrivez la classe Etudiant. Le programme doit gérer en boucle le menu suivant : a) Saisie d 1 tableau Tab1 d Etudiant de 1ere + Affichage b) Saisie d 1 tableau Tab2 d Etudiant de 2ere + Affichage c) Fusion dans un tableau Dynamique les tableaux Tab1 et Tab2 +Affichage Etudiant string Nom; void saisie(); void afficher(); 3.4. Comment concevoir le type classe CLAS de sorte que le programme : void main() { CLAS x; cout << " Salut \n" ; fournisse les résultats suivants : Creation Objet Salut Destruction Objet Saisissez le programme ci-dessous et exécutez le. Quelles sont les valeurs des champs de chaque variable? Que remarquez-vous au sujet de l initialisation des champs? Quand avez vous appelé les constructeurs et destructeurs de chaque variable? Quelles conclusions en tirez vous sur l apport des constructeurs et destructeurs dans la programmation? #include <iostream> using namespace std ; class CLS { int x ; float y ; char z ; CLS( int a = 1, float b = 2.2, char c = 'F' ); ~CLS( ); ; CLS :: CLS( int a, float b, char c ) { //... x = a ; y = b ; z = c ; CLS :: ~CLS( ){ //... void main( ) { CLS var1 ; CLS var2( 20 ) ; CLS var3( 30, ) ; CLS var4( 40, 43.21, 'D' );

38 Chap3 : Les Classes Reprenez l exercice 3.5. et ajoutez une fonction fct permettant de modifier la valeur des champs et une fonction Affichage permettant l affichage des champs de l objet. Puis utilisez deux variables, l une statique et l autre dynamique, en leurs appliquant les appels de fonctions. Quand avez-vous appelé les constructeurs et destructeurs de chaque variable? Quelles conclusions en tirez vous sur l utilisation des variables dynamiques? 3.7. Ecrire un programme utilisant une classe Vecteur3d permettant de manipuler des vecteurs à 3 composantes (x, y, z) de types float. On y prévoira : un constructeur, avec des valeurs par défaut (0), une fonction d'affichage des 3 composantes du vecteur sous la forme : < composante1, composante2, composante3> une fonction permettant d'obtenir la somme de deux vecteurs, une fonction membre coincide(??) permettant de vérifier si deux vecteurs ont les mêmes composantes, la définition d un opérateur == afin de tester la coïncidence ou pas de deux vecteurs, la définition d un opérateur + afin d'additionner deux vecteurs, la définition d un opérateur - afin d'additionner deux vecteurs, Utilisez la fonction main() suivante comme programme d'essai de ce problème et vérifier que les résultats sont conformes à la solution fournie. void main() { vecteur3d v1 (1,2,3), v2 (4,5), w ; cout << "v1 = " ; v1.affiche () ; cout << "\n" ; cout << "v2 = " ; v2.affiche () ; cout << "\n" ; cout << "w = " ; w.affiche () ; cout << "\n" ; w = v1.somme (v2) ; cout << "w = " ; w.affiche () ; cout << "\n" ; w = v1 + v1 ; cout << "w = " ; w.affiche () ; cout << "\n" ; v1.coincide(v2); v1.coincide(v1); if (v1==w) cout << "\n <<< v1 = w"; else cout << "\n >>> v1!= w \n"; ; ; w = v1 - v2 ; cout << "w = " ; w.affiche () ; cout << "\n" w = v1 - v1 ; cout << "w = " ; w.affiche () ; cout << "\n" Affichage de la solution : v1 = < 1, 2, 3> v2 = < 4, 5, 0> w = < 0, 0, 0> w = < 5, 7, 3> w = < 2, 4, 6> ---> === Pas EGALITE === ---> === EGALITE === >>> v1!= w w = < -3, -3, 3> w = < 0, 0, 0>

39 Chap4 : Les patrons et amis Fonctions et classes Parmi les techniques pour améliorer la réutilisabilité des morceaux de code, nous trouvons la notion de généricité. Cette notion permet d écrire du code générique en paramétrant des fonctions et des classes par un type de données. Un module générique n est alors pas directement utilisable : c est plutôt un modèle, patron (template) de module qui sera «instancié» par les types de paramètres qu il accepte. Dans la suite nous allons montrer comment C++ permet, grâce à la notion de patron de fonctions, de définir une famille de fonctions paramétrées par un ou plusieurs types, et éventuellement des expressions. D'une manière comparable, C++ permet de définir des "patrons de classes". Là encore, il suffira d écrire une seule fois la définition de la classe pour que le compilateur puisse automatiquement l'adapter à différents types Patrons de fonctions Pour illustrer les patrons de fonctions, prenons un exemple concret : une fonction min qui accepte deux paramètres et qui renvoie la plus petite des deux valeurs qui lui est fournie. On désire bénéficier de cette fonction pour certains types simples disponibles en C++ (int, char, float). Les notions que nous avons vu en C++ jusqu à maintenant ne nous permettent de résoudre ce problème qu avec une seule solution. Cette solution est d utiliser la surcharge et de définir trois fonctions min, une pour chacun des types considéré. int min (int a, int b) { if ( a < b) return a ; else return b ; // return ((a < b)? a : b); float min (float a, float b) { if ( a < b) return a ; else return b ; char min (char a, char b) { if ( a < b) return a ; else return b ; Définition des fonctions min grâce à la surcharge. Lors d un appel à la fonction min, le type des paramètres est alors considéré et l implantation correspondante est finalement appelée. Ceci présente cependant quelques inconvénients : La définition des 3 fonctions (perte de temps, source d erreur) mène à des instructions identiques, qui ne sont différenciées que par le type des variables qu elles manipulent.

40 Chap4 : Les patrons et amis Fonctions et classes 37 Si on souhaite étendre la définition de cette fonction à de nouveaux types, il faut définir une nouvelle implantation de la fonction min par type considéré. Une autre solution est de définir une fonction template, c est-à-dire générique. Cette définition définit en fait un patron de fonction, qui est instancié par un type de données (ici le type T) pour produire une fonction par type manipulé. template <class T> // T est le paramètre de modèle T min (T a, T b) { if ( a < b) return a else return b; void main(){ int a = min(1, 7); // int min(int, int) float b = min(10.0, 25.0); // float min(float, float) char c = min( z, c ); // char min(char, char) Définition de la fonction min générique. Il n est donc plus nécessaire de définir une implantation par type de données. De plus, la fonction min est valide avec tous les types de données dotés de l opérateur <. On définit donc bien plus qu une fonction, on définit une méthode permettant d obtenir une certaine abstraction en s affranchissant des problèmes de type. Rqs Il est possible de définir des fonctions template acceptant plusieurs types de données en paramètre. Chaque paramètre désignant une classe est alors précédé du mot-clé class, comme dans l exemple : template <class T, class U>... Chaque type de données paramètre d une fonction template doit être utilisé dans la définition de cette fonction. Pour que cette fonctionnalité soit disponible, les fonctions génériques doivent être définies au début du programme ou dans des fichiers d interface (fichiers.h) Classe template : patron de classes Il est possible, comme pour les fonctions, de définir des classes template, c est-à-dire paramétrées par un type de données. Cette technique évite ainsi de définir plusieurs classes similaires pour décrire un même concept appliqué à plusieurs types de données différents. Elle est largement utilisée pour définir tous les types de containers (comme les listes, les tables, les piles, etc.), mais aussi des algorithmes génériques par exemple. La bibliothèque STL (chapitre 6) en particulier propose une implantation d un bon nombre de types abstraits et d algorithmes génériques. La syntaxe permettant de définir une classe template est similaire à celle qui permet de définir des fonctions template. Pour illustrer cela, nous reprenons notre exemple de création de la classe point. Nous avons souvent été amenés à créer une classe point de ce genre :

41 Chap4 : Les patrons et amis Fonctions et classes 38 class point { int x, y ; point (int abs=0, int ord=0) ; void affiche () ; //... ; Lorsque nous procédons ainsi, nous imposons que les coordonnées d'un point soient des valeurs de type int. Si nous souhaitons disposer de points à coordonnées d'un autre type (float, double, long...), nous devons définir une autre classe en remplaçant simplement, dans la classe précédente, le mot clé int par le nom de type voulu. Ici encore, nous pouvons simplifier considérablement les choses en définissant un seul patron de classe de cette façon : template <class T> class point { T x, y ; point (T abs=0, T ord=0) ; void affiche () ; ; Comme dans le cas des patrons de fonctions, la mention template <class T> précise que l'on a affaire à un patron (template) dans lequel apparaît un paramètre de type nommé T ; rappelons qu en C++ le mot clé class précise que T est un argument de type (pas forcément classe...). Bien entendu, la définition de notre patron de classes n'est pas encore complète puisqu'il y manque la définition des fonctions membres, à savoir le constructeur point et la fonction affiche(). Pour ce faire, la démarche va légèrement différer selon que la fonction concernée est en ligne ou non. Pour une fonction en ligne, les choses restent naturelles ; il suffit simplement d'utiliser le paramètre T à bon escient. Voici par exemple comment pourrait être défini notre constructeur: point (T abs=0, T ord=0) { x = abs ; y = ord ; En revanche, lorsque la fonction est définie en dehors de la définition de la classe, il est nécessaire de rappeler au compilateur : que, dans la définition de cette fonction, vont apparaître des paramètres de type ; pour ce faire, on fournira à nouveau la liste de paramètre sous la forme : template <class T> le nom du patron concerné (de même qu'avec une classe "ordinaire", il fallait préfixer le nom de la fonction du nom de la classe...) ; par exemple, si nous définissons ainsi la fonction affiche, son nom sera: point<t>::affiche ()

42 Chap4 : Les patrons et amis Fonctions et classes 39 En définitive, voici comment se présenterait l'en-tête de la fonction affiche si nous le définissions ainsi en dehors de la classe : template <class T> void point<t>::affiche () En toute rigueur, le rappel du paramètre T à la suite du nom de patron (point) est redondant puisqu il a déjà été spécifié dans la liste de paramètres suivant le mot clé template. Voici ce que pourrait être finalement la définition de notre patron de classe point : template <class T> class point { // Création d'un patron de classe T x, y ; point (T abs=0, T ord=0) { x = abs ; y = ord ; void affiche () ; ; template <class T> void point<t>::affiche () { cout << "Paire : " << x << " " << y << "\n" ; Création d'un patron de classes 4.3. Utilisation d un patron de classes Comme pour les patrons de fonctions, l instanciation de tels patrons est effectuée automatiquement par le compilateur selon les déclarations rencontrées. Après avoir créé ce patron, une déclaration telle que : point <int> ai ; conduit le compilateur à instancier la définition d'une classe point dans laquelle le paramètre T prend la valeur int. Autrement dit, tout se passe comme si nous avions fourni une définition complète de cette classe. Si nous déclarons : point <float> ad ; le compilateur instancie la définition d'une classe point dans laquelle le paramètre T prend la valeur float, exactement comme si nous avions fourni une autre définition complète de cette classe. Si nous avons besoin de fournir des arguments au constructeur, nous procéderons de façon classique comme dans : point <int> ai (3, 5) ; point <float> ad (1.5, 9.6) ; Si nous faisons abstraction de la signification des paramètres (coordonnées d un point) et nous les déclarons comme des caractères ou chaînes de caractères, le compilateur ne signalera pas d incohérence et la fonction affiche() remplacera x et y par les arguments, comme le montre l exemple récapitulatif.

43 Chap4 : Les patrons et amis Fonctions et classes 40 Exemple récapitulatif : Voici un programme complet comportant : la création d'un patron de classes point dotée d un constructeur en ligne et d une fonction membre (affiche) non en ligne, la création d un patron de fonctions min (en ligne dans la patron de classes) qui retourne le minimum des arguments, un exemple d'utilisation (main). #include <iostream> #include <string> using namespace std ; template <class T> class point { // Création d'un patron de classe T x ; T y ; point (T abs=0, T ord=0) { x = abs ; y = ord ; void affiche () ; T min () { if ( x < y) return x; else return y; ; template <class T> void point<t>::affiche () { cout << "Paire : " << x << " " << y << "\n" ; void main () { point <int> ai (3, 5) ; // T prend la valeur int pour la classe point ai.affiche() ; cout << " Min :... " << ai.min() << endl; point <char> ac ('z', 't') ; ac.affiche() ; cout << " Min :... " << ac.min() << endl; point <double> ad (1.5, 9.6) ; ad.affiche() ; cout << " Min :... " << ad.min() << endl; point <string> as ("Salut", " A vous") ; as.affiche() ; cout << " Min :... " << as.min() << endl; Programme 4.1. Solution Paire : 3 5 Min :... 3 Paire : z t Min :... t Paire : Min : Paire : Salut A vous Min :... A vous

44 Chap4 : Les patrons et amis Fonctions et classes 41 Rq Le comportement de point<char> est satisfaisant si nous souhaitons effectivement disposer de points repérés par de vrais caractères. En revanche, si nous avons utilisé le type char pour disposer de "petits entiers", le résultat est moins satisfaisant. En effet, nous pourrons toujours déclarer un point de cette façon : point <char> pc (4, 9) ; Mais le comportement de la fonction affiche ne nous conviendra plus (nous obtiendrons les caractères ayant pour code les coordonnées du point!). Il est toujours possible de modifier cela en "spécialisant" notre classe point pour le type char ou encore en spécialisant la fonction affiche pour la classe point<char>. Il faut noter aussi que le nombre de paramètres n'est pas limité à 1, on peut en avoir plusieurs : template < class A, class B, class C,... > class MaClasse { //... public: //... ; L exemple suivant montre comment implémenter les fonctions de la classe template. template <class T, class T1, class T2> class Etudiant{ T Nom, Prenom; T1 Id; T2 Age; public: //... T getnom(){return nom; T1 getid(){return Id; T2 getage(); void Saisie(); void affiche(); //... ; template <class T, class T1, class T2> T2 Etudiant<T,T1,T2>::getAge(){ return Age; template <class T, class T1, class T2> void Etudiant<T,T1,T2>::affiche () { cout << "Data : " << Nom << " " << Id << " " << Age <<"\n" ; La suite de cet exemple sera traitée en séances d exercices. Pour de plus amples informations et plus de détails sur les templates, le lecteur peut se reporter par exemple à l ouvrage référencé au début de ce syllabus : Claude Delannoy Programmer en langage C++, Eyrolles, 2004 ou Chapitre 12.

45 Chap4 : Les patrons et amis Fonctions et classes Fonctions et classes amies Nous avons vu qu une classe avait généralement des membres privés et que ceux-ci n étaient pas accessibles par des fonctions non membres. Cette restriction peut sembler lourde, mais elle est à la base même de la protection des données qui fait une grande partie de la puissance de la programmation par objets en général, et de C++ en particulier. Dans certains cas, cependant, il peut être intéressant d accorder des accès aux attributs ou aux méthodes à certaines classes clientes, tout en protégeant ce même accès vis-à-vis des autres classes. Comment faire alors si par exemple on souhaite qu une fonction f() et/ou une classe B puisse accéder aux données membres privées d une classe A? La solution est de déclarer dans la classe A que f() et/ou B sont amies de A. Voici comment. class A { private: int i; friend class B; // tout ce qui est nécessaire à A // B est autorisée :classe amie // f() est autorisée : fonction amie; pas membre de la classe A friend void f(..); ; class B { // tout ce qui appartient à B, et qui peut se servir des données membres privées de A ; void f(..) {..; Fonctions amies Une fonction amie d'une classe est une fonction qui, sans être membre de cette classe, a le droit d'accéder à tous ses membres, aussi bien publics que privés. Une fonction amie doit être déclarée ou définie dans la classe qui accorde le droit d'accès, précédée du mot réservé friend. Cette déclaration doit être écrite indifféremment parmi les membres publics ou parmi les membres privés : class Tableau { int tab[20], nbr; friend void afficher(tableau t); public: Tableau(int nbrelements);... ; et, plus loin: void afficher(tableau t) { for (int i = 0; i < t.nbr; i++) cout << ' ' << t.tab[i];

46 Chap4 : Les patrons et amis Fonctions et classes 43 Notez que bien que déclarée à l'intérieur de la classe Tableau, la fonction afficher n'est pas membre de cette classe. À part le fait qu elle est amie de la classe Tableau, la fonction est parfaitement ordinaire, et peut être déclarée et définie de la même façon que toute autre. L emploi de friend est une relaxation de la règle de portée textuelle des langages à structure de blocs, car il donne aux fonctions amies les mêmes privilèges que ceux des fonctions membres Méthodes amies Dans la plupart des cas, une fonction amie (4.4.1.) peut avantageusement être remplacée par une fonction membre. Si l on souhaite qu une méthode d une classe puisse accéder aux parties privées d une autre classe, il suffit de déclarer la méthode friend également, en utilisant son nom complet (nom de classe suivi de :: et du nom de la méthode). Par exemple : class Tableau; // déclaration avant celle de la classe Fenetre sinon ERROR class Fenetre {... public: void afficher(tableau t);... ; class Tableau { int tab[20], nbr; public: friend void Fenetre::afficher(Tableau t);... ; Maintenant, la fonction afficher est membre de la classe Fenetre et amie de la classe Tableau : elle a tous les droits sur les membres privés de ces deux classes, et son écriture : Classes amies void Fenetre::afficher( Tableau t) { for (int i = 0; i < t.nbr; i++) cout << ' ' << t.tab[i]; Lorsqu on souhaite que tous les membres d une classe puissent accéder aux parties privées d une autre classe, on peut déclarer «amie» une classe entière : class B ; // déclaration avant celle de la classe A qui contient friend B sinon ERROR class A { private: int i; // tout ce qui est nécessaire à A friend B; // B est autorisée :classe amie ;

47 Chap4 : Les patrons et amis Fonctions et classes 44 class B { // tout ce qui appartient à B, et qui peut se servir des données membres privées de A ; Les membres de la classe B peuvent tous modifier les parties privées des instances de A. La déclaration de B avant celle de A est obligatoire, sinon on obtient Error : Undefined symbol 'B' (symbole 'B' non défini). Pour l éviter, on peut éventuellement changer l ordre de définition, mais il suffit en fait de préciser le sélecteur class derrière friend : class A { private: int i; friend class B; ; // tout ce qui est nécessaire à A // B est autorisée :classe amie Exercices 4.1. Considérons les deux fonctions suivantes : void swap(int& a,int& b) { int tmp=a; a=b; b=tmp; void swap(string& a,string& b) { string tmp=a; a=b; b=tmp; Elles utilisent le même principe, seul le type des deux paramètres (et celui de tmp) changent. Ecrire une seule fois la fonction échange de manière à ce qu elle soit utilisable pour échanger toute paire de variables d un même type Créez deux patrons de fonctions, l un permettant d afficher les éléments et l autre de calculer la somme d un tableau d éléments de type quelconque. Le nom et le nombre d éléments du tableau sont fournis en paramètres Soit la déclaration de la classe vecteur3d de l exercice 3.6. class vecteur3d { float x, y, z ; vecteur3d (float c1=0, float c2=0, float c3=0) { x=c1 ; y=c2 ; z=c3; ; Ecrire une fonction indépendante coincide(??), amie de la classe vecteur3d, permettant de vérifier si deux vecteurs ont les mêmes composantes. Si v1 et v2 désignent deux vecteurs de type vecteur3d, comment s écrit le test de coïncidence de ces deux vecteurs?

48 Chap5 : L'héritage 5.1. Classes de base et classes dérivées L'héritage est un principe propre à la programmation orientée objet, permettant de créer une nouvelle classe à partir d'une classe existante. C est un principe qui permet l extension d'une classe de base afin de lui ajouter des fonctionnalités particulières tout en conservant les fonctionnalités déjà définies dans la classe de base. En fait c est une technique de réutilisation de composants (classes) dont l objectif est la spécialisation de types existants. On parle aussi de la dérivation de classe qui consiste à faire hériter une classe d une autre. Donc une classe B est dérivée d une classe A si elle en hérite. La classe A est alors appelée superclasse ou classe de base ou classe mère de la classe B. On dit aussi que B est la classe fille ou B dérive de A ou encore que B est dérivée de A. Quelque soit le terme choisi, si la classe B hérite de la classe A, alors B possède toutes les propriétés de A; la classe B peut bien sûr avoir des propriétés (données membres, méthodes, ) supplémentaires qui reflètent sa spécificité. En C++, il existe l héritage simple (une classe hérite d une seule classe) et l héritage multiple (une classe peut être dérivée de plusieurs classes). Dans ce cours, nous ne nous intéresserons qu à l'exposé de l héritage simple Mode de dérivation La syntaxe pour la définition d'une classe dérivée est : class ClasseDerivee : < MODE DE DERIVATION > ClasseBase {... ; Dans la définition de la classe dérivée, afin d utiliser l héritage, on ajoute le symbole : après le nom de la classe en précisant par la suite quelle est la classe de base. < MODE DE DERIVATION > permet de spécifier le mode de dérivation et les types de protection par l'emploi d'un des mots-clé suivants : public, protected ou encore private. Le mode de dérivation détermine quels membres de la classe de base sont accessibles dans la classe dérivée. Au cas où aucun mode de dérivation n'est spécifié, le compilateur C++ prend par défaut le mot-clé private pour une classe. Si B hérite de A, B hérite des attributs et des "méthodes" de A. Cependant, la classe B ne peut pas accéder aux membres privés (déclarés private) de la classe A. Faut-il pour autant les déclarer public, au risque de violer le principe d'encapsulation? Le C++ permet de déclarer des membres protégés uniquement accessibles par les objets de la même classe et par tous les objets des classes dérivées. On utilise pour cela le mot clé protected.

49 Chap5 : L'héritage 46 Si le mode de dérivation est : le contrôle d accès est sans changement ; les données publiques de la classebase restent publiques dans la classederivee, protégées restent protégées, privées restent privées ; protected: c'est-à-dire accessibles aux membres de la classe et à ses classes dérivées (par héritage). Dans ce cas, les données publiques deviennent protégées, les données protégées restent protégées et les privées restent privées, private : les données publiques et protégées deviennent privées alors que les données privées restent privées. Le tableau suivant récapitule les propriétés des différentes situations selon le mode de dérivation : mode de dérivation public protected private Statut dans la classe de base public protected private public protected private public protected private public Statut dans la classe dérivée protected inaccessible protected protected inaccessible private private inaccessible Une classe dérivée peut accéder aux membres hérités publics ou protégés mais ne peut accéder aux membres privés hérités. En général, on choisit le mode de dérivation public qui est la forme la plus courante d'héritage. C'est d ailleurs le seul mode que nous traitons dans ce syllabus. Les autres modes seront illustrés par quelques transparents lors des séances d exercices Héritage public Ce mode, comme signalé plus haut, donne aux membres publics et protégés de la classe de base le même statut dans la classe dérivée. Pour spécifier en C++ qu une classe B hérite d une classe A et que le mode de dérivation est public, on déclare la classe B de la manière suivante : class B : public A { // Champs et méthodes ; Plusieurs classes peuvent dériver de la même classe de base. Il est donc possible de représenter sous forme de hiérarchie de classes, parfois appelée arborescence de classes,

50 Chap5 : L'héritage 47 la relation de parenté qui existe entre ces différentes classes. L'arborescence commence par la superclasse (classe de base, classe parent, classe mère ou père). Puis les classes dérivées (classe fille ou sous-classe) deviennent de plus en plus spécialisées. Ainsi, on peut généralement exprimer la relation qui lie une classe dérivée à sa classe de base par la phrase "est un". Classes dérivées Un Etudiant (Enseignant, Agent) est une personne mais pas forcément l inverse. Les déclarations correspondantes à cet arbre peuvent être sous cette forme : class Personne { ; class Agent : public Personne { ; class Enseignant : public Personne{ ; Pour vous présenter la mise en œuvre de l héritage nous commençons à partir d un exemple simple ne faisant intervenir ni constructeur ni destructeur. Nous reprenons le programme 3.2. que nous modifions afin d illustrer les possibilités de l héritage. #include <iostream> #include <string> using namespace std ; class point { private : int x, y; void initialise(int, int) ; void affiche(string) ; ; class Pixel : public point { // Pixel dérive de point int couleur ; void colore (int cl) { couleur = cl; cout << "\n --- couleur = " << couleur << "\n" ; ; void point::initialise (int abs, int ord) { x = abs ; y = ord ;

51 Chap5 : L'héritage 48 void point::affiche (string S) { cout << S << ":- Je suis en " << x << " " << y << "\n" ; void main() { point a; Pixel PC ; // objet de type class point // objet de type class Pixel a.initialise (3, 7) ; a.affiche ("point") ; PC.initialise (10,20) ; PC.colore (5) ; PC.affiche("Pixel") ; Programme 5.1. SOLUTION point:- Je suis en couleur = 5 Pixel:- Je suis en La classe Pixel dérive de la classe point. Le mode de dérivation étant public, les membres publics de la classe de base point sont également publics, donc accessibles et réutilisables dans la classe dérivée Pixel. C est pour cette raison, que dans la fonction main(), les fonctions membres de la classe point, initialise et affiche, sont accessibles par l objet PC de la classe Pixel. Cet objet, comme tout objet de la classe Pixel, peut accéder à sa fonction membre colore contrairement aux objets appartenant à la classe point. La classe Pixel telle qu elle est définie ne permet pas d afficher la couleur d un objet. Une amélioration possible est de créer une fonction qui permet d afficher les coordonnées du point ainsi que sa couleur. Pour afficher les coordonnées on peut réutiliser éventuellement la fonction public affiche de la classe point. Une définition possible de cette fonction est : void Pixel ::AfficheCol (string S){ affiche(s); // membre de la classe de base point cout << "\n --- couleur = " << couleur << "\n" ; Il n est pas possible de remplacer la fonction affiche(s) par son code dans la fonction AfficheCol(S). Autrement dit, la fonction AfficheCol(S) ne peut être définie comme : void Pixel ::AfficheCol (string S){ cout << S << ":- Je suis en " << x << " " << y << "\n" ; cout << "\n --- couleur = " << couleur << "\n" ; En effet, x et y sont des membres privés de la classe point, et ne sont nullement accessible par une fonction membre de la classe dérivée Pixel. C est le principe de l encapsulation.

52 Chap5 : L'héritage Redéfinition de membres dans la classe dérivée Redéfinition des fonctions membres Il est possible, pour une raison ou une autre, de redéfinir une fonction dans une classe dérivée si on lui donne le même nom que dans la classe de base. C est comme si dans l exemple précédent de la classe Pixel, on donne le même nom pour les fonctions affiche et AfficheCol. Dans ce cas, cette dernière deviendrait : void Pixel ::affiche (string S){ // membre de la classe Pixel affiche(s); // membre de la classe de base point cout << "\n --- couleur = " << couleur << "\n" ; L exécution de cette fonction provoquerait des erreurs. En effet, pour le compilateur qui ne fait pas la différence entre les fonctions affiche() de Pixel et de point, c est un appel récursif de cette fonction. Il faut dons faire appel à l opérateur de résolution de portée (::) afin de localiser convenablement la méthode voulue. La fonction sera définie comme suit : void Pixel ::affiche (string S){ // membre de la classe Pixel point :: affiche(s); // membre de la classe de base point cout << "\n --- couleur = " << couleur << "\n" ; Le programme 5.1. peut être transformé de la façon suivante : #include <iostream> #include <string> using namespace std ; class point { private : int x, y; void initialise(int, int) ; void affiche(string) ; ; class Pixel : public point { // Pixel dérive de point int couleur ; void colore (int cl) { couleur = cl; cout << "\n --- couleur = " << couleur << "\n" ; void affiche (string); ; void point::initialise (int abs, int ord) { x = abs ; y = ord ; void point::affiche (string S) { cout << S << ":- Je suis en " << x << " " << y << "\n" ;

53 Chap5 : L'héritage 50 void Pixel ::affiche (string S){ // membre de la classe Pixel point :: affiche(s); // membre de la classe de base point cout << "\n +++ couleur = " << couleur << "\n" ; void main() { point a; Pixel PC ; // objet de type class point // objet de type class Pixel a.initialise (3, 7) ; a.affiche ("point") ; PC.initialise (10,20) ; PC.colore (5) ; PC.affiche("Pixel") ; Programme 5.2. point:- Je suis en 3 7 SOLUTION --- couleur = 5 Pixel:- Je suis en couleur = Redéfinition des données membres C est beaucoup moins courant de redéfinir les données membres. Cependant, ce que nous avons dit à propos de la redéfinition des fonctions membres s applique tout aussi bien aux membres données. class A { int X, Y ; ; class B: public A { float X, Y ; ; 5.5. Héritage et Constructeurs/destructeurs Les constructeurs, constructeur de copie, destructeurs et opérateurs d'affectation ne sont jamais hérités. En fait les constructeurs par défaut des classes de bases sont automatiquement appelés avant le constructeur de la classe dérivée. Afin d illustrer ces propos, le programme suivant en donne un exemple. On remarquera que l'appel des destructeurs se fait dans l'ordre inverse des constructeurs.

54 Chap5 : L'héritage 51 #include <iostream> using namespace std ; class A { public: A() { cout<< "++++ A ++++" << endl; ~A() { cout<< "~~~~ A ~~~~" << endl; ; class B : public A { public: B() { cout<< "++++ B ++++" << endl; ~B() { cout<< "~~~~ B ~~~~ " << endl; ; void main() { B *ObjB = new B; //... delete ObjB; Programme 5.3. SOLUTION ++++ A B ++++ ~~~~ B ~~~~ ~~~~ A ~~~~ Si l on ne désire pas appeler les constructeurs par défaut, mais des constructeurs avec des paramètres, on doit utiliser une liste d'initialisation. Le programme qui nous servira d exemple est une adaptation du programme 5.2. #include <iostream> using namespace std ; class point { int x, y ; point (int abs=0, int ord=0) { // constructeur de point ("inline") cout << "++ constr. point :" << abs << " " << ord << "\n" ; x = abs ; y =ord ; ~point(){ cout<< "~~~~ point ~~~~" << endl; ;

55 Chap5 : L'héritage 52 class Pixel : public point { int couleur ; Pixel (int, int, int) ; // déclaration constructeur Pixel ~Pixel(){ cout<< "~~~~ Pixel ~~~~ :" << couleur << endl; ; Pixel::Pixel (int abs, int ord, int cl) { cout << "++ constr. Pixel : " << abs << " " << ord << " " << cl << "\n"; couleur = cl ; void main() { Pixel a(10,15,3); Programme 5.4. SOLUTION ++ constr. point : constr. Pixel : ~~~~ Pixel ~~~~ : 3 ~~~~ point ~~~~ La déclaration : Pixel a(10, 15, 3) ; entraînera : l appel de point qui recevra les arguments les arguments par défaut 0 et 0, l appel de Pixel qui recevra les arguments 10, 15 et 3. Si maintenant le constructeur de la classe point n avait pas d arguments par défaut, donc déclaré comme ceci : point (int abs, int ord) { voici l erreur de compilation que l on peut avoir : error C2512: 'point' : no appropriate default constructor available Si par contre on souhaite que Pixel retransmette à point les deux premières informations reçues, on écrira son en-tête de cette manière : Pixel::Pixel (int abs, int ord, int cl) : point (abs, ord) Le compilateur mettra en place la transmission au constructeur de point des informations abs et ord correspondant aux deux premiers arguments de Pixel. Ainsi la déclaration : Pixel a (10, 15, 3) ; entraînera : l appel de point qui recevra les arguments 10 et 15, l appel de Pixel qui recevra les arguments 10, 15 et 3.

56 Chap5 : L'héritage 53 En revanche, la déclaration : Pixel b (1, 7) ; provoquera une erreur puisqu il n existe pas de constructeur Pixel à deux arguments. Bien entendu, il reste la possibilité d initialiser les arguments par défaut, par exemple : Pixel::Pixel (int abs=0, int ord=0, int cl=9) : point (abs, ord) Dans ces conditions, la déclaration : Pixel c (2) ; entraînera : l appel de point qui recevra les arguments 2 et 0, l appel de Pixel qui recevra les arguments 2, 0 et 9. Notez que la présence éventuelle d arguments par défaut dans point n a aucune incidence ici. La déclaration : Pixel * adr ; adr = new Pixel (20,30) ; // objet dynamique entraînera : l appel de point qui recevra les arguments 20 et 30, l appel de Pixel qui recevra les arguments 20, 30 et Polymorphisme Considérons les deux classes CLA et CLB ; class CLA { void Affiche() { cout << " Affichage:CLA " << endl ; ; class CLB : public CLA { void Affiche() { cout << " Affichage:CLB " << endl ; ; La classe CLB dérive de la classe CLA et redéfinit (surcharge) la fonction Affiche(). Voyons un exemple d utilisation simple. CLA *ptr_a = new CLA ; CLB *ptr_b = new CLB ; CLA *ptr ; ptr = ptr_a; ptr Affiche(); // Affichage:CLA ptr = ptr_b; ptr Affiche(); // Affichage:CLA Le problème réside dans le deuxième appel de la méthode Affiche(). En effet, bien que le pointeur ptr fasse référence à une instance de type CLB, c est la méthode Affiche() de CLA (le type initial de ptr) qui est appelée. Ce comportement n est généralement pas celui souhaité ; on préfère que la méthode appelée soit celle du type de l objet auquel le pointeur fait référence. On voudrait que le pointeur puisse être polymorphe (change de forme, de nature).

57 Chap5 : L'héritage 54 Le polymorphisme est un concept des langages objet qui découle directement de l'héritage. Si ce dernier permet de réutiliser le code écrit pour la classe de base dans les classes dérivées, le polymorphisme rendra possible l'utilisation d'une même instruction pour appeler dynamiquement des méthodes différentes dans la hiérarchie des classes. Le polymorphisme réside donc dans la capacité d'un objet à modifier son comportement propre et celui de ses descendants au cours de l'exécution. En C++, Il faut indiquer au compilateur qu'il a affaire à une fonction polymorphe, sinon il serait tenté d'utiliser la fonction de la classe de base. Le polymorphisme est mis en oeuvre par l'utilisation des fonctions virtuelles. Une fonction virtuelle est une fonction qui possède la capacité de "changer de forme" dans les classes dérivées de la classe de base définissant la méthode virtuelle. Un mot clé est alors introduit : virtual. Ce mot clé est placé devant la déclaration de la méthode. Dans notre exemple il suffit d ajouter virtual dans les classes devant les fonctions concernées. Les déclarations des classes deviennent alors : class CLA { virtual void Affiche() { cout << " Affichage:CLA " << endl ; ; class CLB : public CLA { virtual void Affiche() { cout << " Affichage:CLB " << endl ; ; Il n est pas obligatoire de répéter le mot-clef virtual dans CLB mais améliore la lisibilité du code. Le code qui posait problème a maintenant le comportement voulu, sans rien y changer et le compilateur choisit la bonne méthode, celle qui doit être appelée lors de l'exécution : ptr = ptr_a; ptr Affiche(); // Affichage:CLA ptr = ptr_b; ptr Affiche(); // Affichage:CLB Rq Il est généralement conseillé d'utiliser le mot clé virtual devant la déclaration du desctructeur de la classe de base, afin que celui des sous-classes soit appelé également lorsque le programme utilise un pointeur d'instance de la classe de base au lieu d'un pointeur d'instance de la classe dérivée.

58 Chap5 : L'héritage 55 Exercices 5.1. Remplacez dans le code du programme 5.4. Pixel::Pixel (int abs, int ord, int cl) { par Pixel::Pixel (int abs=0, int ord=0, int cl=9) : point (abs, ord){ puis, donnez un exemple d instructions dans la fonction main() qui aboutira à la solution suivante : ++ constr. point : constr. Pixel : constr. point : constr. Pixel : constr. point : constr. Pixel : constr. point : constr. Pixel : ~~~~ Pixel ~~~~ :9 ~~~~ point ~~~~ ~~~~ Pixel ~~~~ :9 ~~~~ point ~~~~ ~~~~ Pixel ~~~~ :9 ~~~~ point ~~~~ ~~~~ Pixel ~~~~ :3 ~~~~ point ~~~~ 5.2. Saisissez le programme et exécutez-le. Quand est appelé le constructeur de A, de B? Quelles sont les valeurs des champs de la variable b à la fin du programme? Comment l expliquez-vous? Que faut-il faire pour modifier uniquement la valeur du champ x? Quel est l intérêt du mot protected? #include <iostream> using namespace std ; class ClsA { protected : int x ; void f ( int ) ; ClsA ( int a = 3 ) ; ; ClsA :: ClsA ( int a ) { x = a ; void ClsA :: f ( int i ) { x = i; class ClsB : public ClsA { int y ; ClsB ( int a ) ; void g ( ) ; ; ClsB ::ClsB ( int a ) : ClsA ( 2*a ) { y = a ; void ClsB :: g ( ) { cout << "Les valeurs sont x = " << x << "\ny = " << y << "\n" ; void main ( ) { ClsB b ( 10 ) ; b.g ( ) ;

59 Chap5 : L'héritage Le poulailler Implémentez la hiérarchie de classes en face : la classe de base Volaille et ses classes dérivées : Poule, Coq, Œuf ainsi que les différentes fonctions membres. On considère que le poids d un œuf = 0,1 poids de la poule. Il est possible d ajouter des paramètres aux fonctions et/ou d ajouter d autres fonctions. Ce programme doit gérer en boucle le Menu suivant : 1- Créer un Tableau Dynamique de poules + Affichage 2- Créer un coq + Affichage 3- Le coq fait cocorico et toutes les poules pondent 4- Le coq dit CoCo et une poule/2 pond 5- Fin (on tue tout le poulailler!!) 1- Créer Tableau Dynamique de Poules et Affichage: Est constitué au moins de deux fonctions : SaisiePoule (.) ; Dans cette fonction on demandera et on testera le nombre de Poules (NP<Max=10) à saisir et on effectuera la saisie dans un Tableau Dynamique. Poule int Poids ; void saisie(); void affiche(); void pondre(??); Oeuf char Qualite; void saisie(); void affiche(); Volaille string Nom ; void saisie(); void affiche(); Coq char * Description ; void saisie(); void affiche(); void cocorico(??); void CoCo(??); Voici un exemple d exécution du programme Menu : ******* 1. Créer un Tb Dyn poule + Af. 2. Créer un coq + Affichage 3. Le coq fait cocorico et toutes les poules pondent 4. Le coq dit CoCo poule/2 5. Fin Choix : 1 Combien de poules? : 4 Le Nom? : Poule1 Le poids? : 200 Le Nom? : Poule2 Le poids? : 180 Le Nom? : Poule3 Le poids? : 1200 Le Nom? : Poule4 Le poids? : 1000 Poule4 (1000) Poule3 (1200) Poule2 (180) Poule1 (200) Menu : ******* Choix : 2 Le Nom? : M_CoQ Description? : BeauCoQ Son Nom : M_CoQ Description : BeauCoQ Menu : ******* Choix : 3 L'oeuf a bien ete pondu et pese : 100(gr) Qualite de l'oeuf (A,B ou C)? : A L'oeuf a bien ete pondu et pese : 120(gr) Qualite de l'oeuf (A,B ou C)? : B L'oeuf a bien ete pondu et pese : 18(gr) Qualite de l'oeuf (A,B ou C)? : A L'oeuf a bien ete pondu et pese : 20(gr) Qualite de l'oeuf (A,B ou C)? : C Menu : ******* Choix : 4 (Une poule sur 2) L'oeuf a bien ete pondu et pese : 100(gr) Qualite de l'oeuf (A,B ou C)? : A L'oeuf a bien ete pondu et pese : 18(gr) Qualite de l'oeuf (A,B ou C)? : A Rqs : Normalement pas de Classe amie. strcpy(chaine1,chaine2) permet de copier la chaine2 (char []) dans chaine1 (char []). Si par contre chaine2 est un string alors il faut écrire strcpy(chaine1,chaine2.c_str()) Utilisez les règles de bonnes pratiques étudiées durant les travaux pratiques telles que l indentation syntaxique, la programmation modulaire, libération de mémoire.

60 Chap5 : L'héritage Implémentez la hiérarchie de classes suivante : Personne string nom, prenom; void saisie(); void afficher(); Etudiant int NumCarte; int AnEtud; int Note[3]; void saisie(); void afficher() Prof string Service; float Salaire; void saisie(); void afficher(); Direction string Titre; void saisiedir(); void afficherdir();.. Ensuite, implémentez un programme qui doit gérer en boucle le Menu suivant : 1. Saisie et/ou Ajout Etudiants et affichage 2. Saisie et/ou Ajout Profs et affichage 3. Doyen membre de Direction Calcul Moyenne étudiant et affichage 4. Cherche un Prof selon son nom 5. Cherche un Etudiant selon son nom 6. Quitter; Dans 1. et 2. on utilisera des tableaux dynamiques. Optimisez votre code et utilisez des templates quand c est nécessaire.

61 Chap6 : La bibliothèque STL 6.1. Introduction La bibliothèque STL (Standard Template Library : Bibliothèque standard générique.) est certainement l un des atouts de C++ et peut être considérée comme un outil très puissant. Il s agit d un ensemble de structures de données (des conteneurs) et d algorithmes suffisamment performants pour répondre aux besoins usuels des programmeurs et leur faciliter la tâche. Afin de rendre ces composants génériques, ils sont implémentés pour la plupart à l'aide de patrons (templates) de classe ou de fonction. Cette bibliothèque fournit ces composants : un ensemble de classes conteneurs (collections d'objets), tel que les vecteurs, les tableaux associatifs, les listes chaînées, qui peuvent être utilisées pour contenir n'importe quel type de données à condition qu'il supporte certaines opérations comme la copie et l'assignation. une abstraction des pointeurs : les iterators. Ceux-ci fournissent un moyen simple et élégant de parcourir des séquences d'objets et permettent la description d'algorithmes indépendamment de toute structure de données. des algorithmes génériques tels que des algorithmes d'insertion/suppression, recherche et tri. une classe string (déjà utilisée) permettant de gérer efficacement et de manière sûre les chaînes de caractères. L objectif de ce chapitre n est pas de présenter tous les détails de STL, vu le temps imparti à ce cours, mais simplement de fournir un début de notions sur le sujet. Des compléments d informations peuvent se trouver par exemple sur : manuel d utilisation de STL en anglais. : Un excellent tutorial en anglais. ou un certain nombre d ouvrages, en plus des références données au début du syllabus, comme : La bibliothèque standard STL du C++ Alain Bernard Fontaine chez MASSON Pour mieux développer avec C++ : design patterns, STL, RTTI et smart pointers Aurélien Geron & Fatmé Tawbi chez DUNOD 6.2. Les conteneurs Les containers ou conteneurs sont des objets décrits par des classes génériques représentant les structures de données logiques les plus couramment utilisées : les listes (list), les vecteurs (vector), les ensembles (set), les listes d'associations (map),... Ces classes sont dotées de méthodes permettant d'organiser un ensemble de données en séquence, puis de parcourir ces données. Ces méthodes permettent de créer, de copier, de détruire ces containers, d y insérer, de rechercher ou de supprimer des éléments. La

62 Chap6 : La bibliothèque STL 59 gestion de la mémoire, l allocation et la libération, est contrôlée directement par les containers, ce qui facilite leur utilisation. Tous les conteneurs proposent les méthodes suivantes : empty() : teste si le conteneur est vide, max_size() : retourne taille limite, size() : retourne taille actuelle, operator=() : affectation d'un conteneur dans un autre, operator<(), operator<=(), operator>() operator>=(), operator==(), operator!=() opérateurs de comparaison, swap() : échange les éléments de deux conteneurs, erase() : supprime un ou plusieurs éléments, clear() : supprime tous les éléments, begin() : retourne un itérateur qui pointe sur le 1er élément du conteneur ; end() : retourne un itérateur qui pointe après le dernier élément du conteneur ; rbegin() : retourne un itérateur qui pointe sur le dernier élément du conteneur (pour parcours du conteneur en sens inverse) rend() : retourne un itérateur qui pointe avant le 1er élément du conteneur (pour parcours du conteneur en sens inverse) Dans ce chapitre nous nous intéressons uniquement aux conteneurs list et vector. Après l introduction de la notion d itérateur nous donnons un programme exemple dont le but est d illustrer un certain nombre de méthodes disponibles sur ces conteneurs. Pour les utiliser, il suffit d inclure dans le programme <list> et <vector> Vector Le but de cette classe est de généraliser la notion de tableau. Sa structure interne est un tableau dynamique qui est redimensionnable, automatiquement ou manuellement. A tout moment, il est possible d'ajouter un élément, il n'y a pas de limitation (hormis l'espace mémoire). Ainsi, si le tableau interne est plein au moment de l'ajout d'un nouvel élément, alors il est réalloué avec une taille plus importante et tous ses éléments sont recopiés dans le nouvel espace. vector<int> v; for (int i=0; i<100; i++) v.push_back(i); // insérer un nouvel élément à la fin du container Cependant, il est possible de contrôler à l'avance la taille du tableau interne (grâce à la méthode reserve), ce qui permet d'éviter la réallocation du tableau. vector<int> v; v.reserve(10); for (int i=0; i<10; i++) v.push_back(i);

63 Chap6 : La bibliothèque STL 60 Il est aussi possible d'initialiser un vecteur rempli d'un certain nombre d'éléments. Ces derniers sont créés à partir du constructeur par défaut de leur classe. vector<int> v(10); // v est construite avec 10 éléments for (int i=0; i<10; ++i) v[i]=i; Il est possible d'accéder directement à un élément d'un vecteur à partir de son index, en utilisant l'opérateur [ ]. La numérotation des éléments débute à zéro, comme pour un tableau classique List La liste propose un ajout et une suppression en début de liste. La structure interne du conteneur est une liste dynamique doublement chaînée dédiée à la représentation séquentielle de données. Si l opérateur [ ] qui permet d accéder directement à un élément est disponible sur les objets de type vector, il ne l est pas sur ceux de type list. L accès aux éléments ainsi que l'ajout et la suppression en milieu de liste sont rendus possibles par l'intermédiaire des itérateurs. Grâce à la structure de liste chaînée, ces opérations sont très efficaces. Il existe également des fonctions spécifiques à la classe générique list. Voici par exemple comment créer une liste d entiers : list<int> Liste1, Liste2; // liste d'entiers vide Il est aussi possible d'initialiser une liste avec la même valeur. Le premier argument du constructeur fournit le nombre d éléments de la liste (5), le second la valeur (77) de chaque nœud. list<int> Liste(5, 77); // construite avec 5 éléments de type int ayant tous la valeur 77 Pour accéder à la valeur de tête ou de queue : Liste.front(); // Retourne la valeur en tête de liste Liste.back(); // Retourne la valeur en queue de liste Ces 2 fonctions retournent des références, c'est-à-dire qu'on peut s'en servir pour modifier le premier où le dernier élément d'une liste. Par exemple Liste.front() = 5 ; 6.3. Les itérateurs Les itérateurs sont des pointeurs spécialisés qui accèdent aux éléments d'un conteneur. Un itérateur sur un conteneur ne peut être créé que par le conteneur même. Chaque conteneur fournit un itérateur portant le nom iterator (même const_iterator, reverse_iterator ) Il est doté d une méthode begin qui renvoie un itérateur sur le premier de ses éléments, et d une méthode end qui renvoie un itérateur sur une place se trouvant juste après le dernier élément. Un itérateur peut être incrémenté en utilisant l opérateur ++ (attention, ne pas utiliser -- pour reculer, ça ne marche pas toujours), et accéder à l'élément pointé par

64 Chap6 : La bibliothèque STL 61 l'opérateur *. Les opérateurs == et!= sont également disponibles pour vérifier si deux itérateurs pointent au même endroit. L'exemple suivant montre comment effectuer les parcours direct et inverse séquentiellement d un conteneur de son début à sa fin : list<int> Liste ; list<int> ::iterator it ; list<int> ::reverse_iterator rit ; // itérateur direct sur une liste de int // itérateur inverse sur une liste de int for (it= Liste.begin() ; it!= Liste.end() ; it++) { cout << *it << endl; // *it désigne l élément courant de la liste for (rit= Liste.rbegin() ; rit!= Liste.rend() ; rit++) { cout << *rit << endl; // *rit désigne l élément courant de la liste Le programme suivant présente une application de deux conteneurs de séquence: vector (vecteur) et list (liste). Nous exposons un certain nombre de méthodes qui sont disponibles sur tous les types de conteneurs. Pour le reste des méthodes nous invitons le lecteur motivé à consulter les références ou faire une petite balade sur le net. #include <iostream> #include <string> #include <vector> #include <list> using namespace std; void Affiche_V(vector<int> V){ cout << "VECTOR" << " : "; for (int i=0; i< V.size() ; i++) { cout <<V[i] <<" "; cout << endl; void Affiche_L(list<int>::iterator it, list<int> Liste, string S){ cout << S << " : "; if(liste.empty()) cout<<"la liste est vide "<<endl; else for (it= Liste.begin() ; it!= Liste.end() ; it++) { cout << *it << " "; cout << endl; // *it désigne l'élément courant de la liste void R_Affiche_L(list<int>::reverse_iterator it, list<int> Liste, string S){ cout << S << " : "; for (it= Liste.rbegin() ; it!= Liste.rend() ; it++) { cout << *it << " "; // *it désigne l'élément courant de la liste cout << endl;

65 Chap6 : La bibliothèque STL 62 void main() { // appel de constructeurs sans arguments et construit un conteneur vide vector<int> Tab; // Crée un tableau d'entiers vide sans dim list<int> Liste1, Liste2; // Crée deux listes d'entiers vides list<int> ::iterator it ; list<int> ::reverse_iterator rit ; int i; // itérateur direct sur une liste de int // itérateur inverse sur une liste de int // Saisie des entiers cout << "Saisir le prochain entier (-1 pour finir) : "; cin >> i; while (i!= -1) { Liste1.push_back(i); Liste2.push_front(i); Tab.push_back(i); // pas de Tab.push_front(i); cout << "Saisir le prochain entier (-1 pour finir) : "; cin >> i; // Affichage des données Affiche_V(Tab); Affiche_L( it, Liste1, "LISTE1"); Affiche_L( it, Liste2, "LISTE2"); R_Affiche_L( rit, Liste1, "LISTE1 Inverse"); // Nombre d'éléments des containers cout << "Il y a " << Tab.size() << " Elements dans le tableau" << endl; cout << "Il y a " << Liste1.size() << " Elements dans la liste1" << endl; // Accès à des éléments cout << "Premier et dernier element du tableau : " << Tab.front() << " ; "<< Tab.back()<< endl; cout << "Premier et dernier element de la liste1 : " << Liste1.front() << " ; "<< Liste1.back() << endl; int milieu = Tab.size()/2; cout << "Element de milieu de tableau : " << Tab[milieu] << endl; // supprimer et ajouter des éléments cout << "Sup Dernier " << endl; Liste1.pop_back(); Affiche_L( it, Liste1, "LISTE1"); Tab.pop_back(); Affiche_V(Tab); cout << "Sup premier " << endl; Liste1.pop_front(); Affiche_L( it, Liste1, "LISTE1"); // pas de pop_front() pour Tab cout << "ERASE premier+2" << endl; Tab.erase(Tab.begin()+2); Affiche_V(Tab);

66 Chap6 : La bibliothèque STL 63 cout << "Inserer dernier-1" << endl; Tab.insert(Tab.end()-1, 99); Affiche_V(Tab); cout << "ERASE Segment entre 1er et dernier" << endl; Tab.erase(Tab.begin()+1, Tab.end()-1); Affiche_V(Tab); cout << "Tout Effacer " << endl; Tab.clear(); Affiche_V(Tab); Programme 6.1. Résultats de l'exécution Saisir le prochain entier (-1 pour finir) : 1 Saisir le prochain entier (-1 pour finir) : 2 Saisir le prochain entier (-1 pour finir) : 55 Saisir le prochain entier (-1 pour finir) : 33 Saisir le prochain entier (-1 pour finir) : 4 Saisir le prochain entier (-1 pour finir) : 9 Saisir le prochain entier (-1 pour finir) : 7 Saisir le prochain entier (-1 pour finir) : -1 VECTOR : LISTE1 : LISTE2 : LISTE1 Inverse : Il y a 7 Elements dans le tableau Il y a 7 Elements dans la liste1 Premier et dernier element du tableau : 1 ; 7 Premier et dernier element de la liste1 : 1 ; 7 Element de milieu de tableau : 33 Sup Dernier LISTE1 : VECTOR : Sup premier LISTE1 : ERASE premier+2 VECTOR : Inserer dernier-1 VECTOR : ERASE Segment entre 1er et dernier VECTOR : 1 9 Tout Effacer VECTOR : Rqs Le parcours de la liste ne peut se faire qu à l aide d un itérateur et ne peut se faire comme pour vector à l aide de : for (i=0; i< N ; i++). L utilisateur n a pas à se soucier de l allocation ou de la libération de la mémoire. C est vrai lors de l insertion d éléments (.push_back(i);.push_front(i);.insert) et aussi à la fin du programme : aucune instruction particulière n est nécessaire pour restituer la mémoire occupée par les conteneurs. À la sortie du bloc dans lequel ils sont définis, leur destructeur se charge de libérer toutes les ressources occupées.

67 Chap6 : La bibliothèque STL Les algorithmes Les algorithmes sont des patrons de fonction dans la STL permettant d effectuer des opérations et des manipulations des données sur les conteneurs. Afin de pouvoir s appliquer à plusieurs types de conteneurs, les algorithmes ne prennent pas de conteneurs en arguments, mais des itérateurs qui permettent de désigner une partie ou tout un conteneur. Nous n'allons pas détailler ici tous les algorithmes, nous invitons le lecteur à consulter la documentation pour plus d'informations. Nous signalons juste qu il existe : sort() : Trie par ordre croissant les éléments entre début et fin à l intérieur d un conteneur sort (Itérateur début, Itérateur fin); Exemple : sort(v.begin(),v.end()); find() : Trouver la position de Valeur entre début et fin. Retourne comme résultat un itérateur sur cet élément. find(itérateur début, Itérateur fin, const Type&Valeur); Exemple : find(v.begin(),v.end(), 15); search() : Trouver la position de la sous-séquence comprise entre début2 et fin2 à l intérieur de la séquence comprise entre début1 et fin2. search(itér début1, Itér fin1, Itér début2, Itér fin2); Exemple : search(v1.begin(), v1.end(), v2.begin(), v2.end()); unique() : Supprimer les doublons dans la séquence source (appliquer aux couples d'éléments successifs). replace() : Remplacer tous les val1 par val2 entre début et fin. replace(itér début, Itér fin, const Type&Va11, const Type&Va12); Exemple:replace(v.begin(),v.end(), 2, 4); // Remplace tous les 2 par des 4 reverse() : Inverser l'ordre des éléments d'une séquence. Exemple : reverse(v.begin(),v.end()) ; min_elementet() et max_element(): Retournent un itérateur référençant respectivement le plus petit et le plus grand des éléments de la séquence. Exemple : cout << *min_element(v.begin(),v.end()) << endl; cout << *max_element(t, t+10) << endl; lower_bound() et upper_bound() : Recherche binaire déterminant la première et la dernière position à laquelle Val peut être insérée dans la séquence ordonnée spécifiée par les itérateurs début et fin sans en briser l'ordre. lower_bound (Itér début, Itér fin, const Type&Va1); upper_bound (Itér début, Itér fin, const Type&Va1); Exemple : lower_bound(v.begin(),v.end(), 5) ;

68 Chap6 : La bibliothèque STL 65 merge() : Fusionner deux listes d éléments ordonnées. Exemple : Liste3.merge(Liste2); // Liste3 = Liste3 + Liste2 en s'appuyant sur l'opérateur >; à la fin Liste2 est vide copy() : Recopie l intervalle [v.begin(), v.end()] à partir de la position L.begin(). Copy(v.begin(), v.end(), L.begin() ) ; remove() : Supprime les éléments valant Val de la séquence [v.begin(), v.end()]. remove(v.begin(), v.end(), Val); /* En réalité, remove() place les éléments égaux à la fin du conteneur ; la suppression se fera ultérieurement par la méthode erase du conteneur */ Pour utiliser ces algorithmes, il suffit d inclure dans le programme <algorithm>. Voici un programme d utilisation de certains algorithmes. #include <iostream> #include <string> #include <vector> #include <list> #include <algorithm> using namespace std; void Affiche_V(vector<int> V, string S){ cout << S << " : "; for (int i=0; i< V.size() ; i++) { cout <<V[i] <<" "; cout << endl; void Affiche_L(list<int>::iterator it, list<int> Liste, string S){ cout << S << " : "; for (it= Liste.begin() ; it!= Liste.end() ; it++) { cout << *it << " "; cout << endl; void main() { int T1[7] = { 3, 5, 9, 1, 4, 18, 5; int T2[5] = { 9, 1, 7, 2, 5; int TT[15]={0; vector<int> V1(T1, T1+7), V2(T2, T2+5), VV(TT, TT+15); Affiche_V(V1, "Vect1 Initial"); Affiche_V(V2, "Vect2 Initial"); Affiche_V(VV, " VV Initial"); int Seq[2] = {9, 1; int *p; p = search(t1, T1+7, Seq, Seq+2); cout << "... En Vect1 :{9,1 en position " << p - T1 << endl;

69 Chap6 : La bibliothèque STL 66 p = search(t2, T2+5, Seq, Seq+2); cout << "... En Vect2 :{9,1 en position " << p - T2 << endl; sort(v1.begin(), V1.end()); sort(v2.begin(), V2.end()); Affiche_V(V1, "Vect1 Trie "); Affiche_V(V2, "Vect2 Trie "); cout << "Min 1 : " << *min_element(v1.begin(),v1.end()) << endl; cout << "Max It1: " << *max_element(t1, T1+7) << endl; cout << "Max T1 : " << *max_element(v1.begin(),v1.end()) << endl; sort(t1, T1+7); // Détermine les positions possibles d'insertion d'un 5 : cout << "Pour Vect1 Trie: 5 peut etre insere de " << lower_bound(t1, T1+7, 5) - T1 << " a " << upper_bound(t1, T1+7, 5) - T1 << endl; reverse(v1.begin(), V1.end()); Affiche_V(V1, "Vect1 Trie Reverse"); replace(v1.begin(), V1.end(), 5, 4); Affiche_V(V1, "Vect1 Trie Reverse Replace 5 par 4"); Affiche_V(VV, "Vect Avant "); copy(v1.begin(), V1.end(), VV.begin() ) ; Affiche_V(VV, "Vect + V1 "); copy(v2.begin(), V2.end(), VV.begin()+7 ) ; Affiche_V(VV, "Vect +V1+V2 "); sort(vv.begin(), VV.end()); Affiche_V(VV, "Vect Trie "); list<int> L1, L2, L3; list<int> ::iterator it ; L1.insert(L1.begin(),VV.begin(), VV.end()); Affiche_L(it, L1, "Liste L1 "); L1.unique(); Affiche_L(it, L1, "L1 Unique "); L1.remove(4); // supprime tous éléments égaux à 4 Affiche_L(it, L1, "L1-4 "); L2.push_front(5); // L2 : 5 L2.push_front(7); // L2 : 7 5 L2.push_back(4); // L2 : L2.push_back(2); // L2 : L2.push_front(3); // L2 : Affiche_L(it, L2, "L2 :... "); L2.sort(); Affiche_L(it, L2, "L2 Trie..."); Affiche_L(it, L1, "L1 :... ");

70 Chap6 : La bibliothèque STL 67 L2.merge(L1); Affiche_L(it, L2, "L2 merge L1 "); Affiche_L(it, L1, "L1 apres merge..."); L2.unique(); Affiche_L(it, L2, "L2 Unique "); L3.push_front(99); L3.splice(L3.end(),L2); Affiche_L(it, L3, "L3 splice L2 : "); Affiche_L(it, L2, "L2 apres splice... "); Programme 6.2. Résultats de l'exécution Vect1 Initial : Vect2 Initial : VV Initial : En Vect1 :{9,1 en position 2... En Vect2 :{9,1 en position 0 Vect1 Trie : Vect2 Trie : Min 1 : 1 Max It1: 18 Max T1 : 18 Pour Vect1 Trie: 5 peut etre insere de 3 a 5 Vect1 Trie Reverse : Vect1 Trie Reverse Replace 5 par 4 : Vect Avant : Vect + V1 : Vect +V1+V2 : Vect Trie : Liste L1 : L1 Unique : L1-4 : L2 :... : L2 Trie... : L1 :... : L2 merge L1 : L1 apres merge... : L2 Unique : L3 splice L2 : : L2 apres splice... :

71 Chap6 : La bibliothèque STL 68 Exercices 6.1. Remplacez dans le code de l exercice 5.3.du poulailler le tableau dynamique par une liste Remplacez dans le code de l exercice 5.4. les tableaux dynamiques par des listes Complétez la fonction void OrderedList<T> ::add(const T& t) { #include <iostream> #include <list> #include <string> using namespace std; template <class T> class OrderedList : public list<t> { public: void add(const T&); ; void main() { OrderedList<string> nom; nom.add(string("toto")); nom.add(string("mimi")); nom.add(string("picsou")); nom.add(string("aladin")); nom.add(string("jasmine")); list<string>::const_iterator it=nom.begin(); while (it!=nom.end() ) cout << *it++ << endl; template <class T> void OrderedList<T>::add(const T& t) {... pour que ce programme affiche le résultat suivant sans utiliser la fonction prédéfinie de l algorithme sort(). Aladin Jasmine Mimi Picsou Toto 6.4. Donnez le code d un programme qui crée une liste L1 contenant les 10 premières lettres de l alphabet, crée une nouvelle liste L2 égale à L1 et efface d un bloc la première moitié de L Donnez le code d un programme qui crée un vecteur v1 de 10 float régulièrement répartis entre 0.0 (inclus) et 1.0 (non compris), crée un nouveau vecteur v2 égal à v1 et efface élément par élément la deuxième moitié de v Donnez le code d un programme qui crée un vecteur de 5 string de longueurs différentes, affiche ces chaînes, les trie par ordre lexicographique et réaffiche les chaînes triées Donnez le code d un programme qui crée une liste de string représentant la phrase il fait beau, trouve la position du mot beau et insère le mot tres à la position précédente.

72 Chap6 : La bibliothèque STL En utilisant l algorithme find de STL et les templates, donnez le code de la fonction Test pour que ce programme affiche le résultat suivant: void main() { vector<string> V(3); vector<string>::iterator itv; V[0]="V0"; V[1]="V1"; V[2]="V2"; string St1="V1", St2="V5"; Test(V, itv, St1, "Vecteur"); Test(V, itv, St2, "Vecteur"); list<int> L; list<int>::iterator itl; for( int i = 0; i < 5; i++ ) { L.push_back(i); int x=10, y=2; Test(L, itl, x, "List"); Test(L, itl, y, "List"); Test Vecteur V1 est dans Vecteur Test Vecteur V5 n'est pas dans Vecteur Test List 10 n'est pas dans List Test List 2 est dans List 6.9. Ecrivez les 2 classes Etudiant et Personne. La classe Etudiant hérite de la classe Personne. Si nécessaire, des fonctions membres peuvent être ajoutées aux classes. Ce programme doit gérer en boucle le Menu suivant : 1) Saisie d 1 List d Etudiant de 1ere (insertion en Fin) 2) Saisie d 1 Vector d Etudiant de 2d (insertion au début) 3) Calculer et afficher le nombre de filles (F) dans la liste List. Personne string Nom; void saisie(); void afficher(); Etudiant int Note[2]; char sexe ; void saisie(); void afficher()

73 Chap6 : La bibliothèque STL Donnez le code d un programme qui manipule deux classes : Une classe Etudiant dont les objets sont des étudiants caractérisés par int Id; string nom; Une seconde classe Prof dont les objets sont des enseignants caractérisés par int Id; string nom, Service; Dans les deux classes (étudiants, enseignants), on déclarera au moins deux méthodes, l une pour saisir et l autre pour afficher chaque objet de la classe (Saisie() et Affichage() ). La manipulation des étudiants se fera en utilisant un conteneur List alors que les Profs seront rangés dans un conteneur Vector. Ce programme doit gérer en boucle le menu suivant : A : Etudiants ou B : Profs 1 : Saisie et Affichage d une List (Etud.) ou Vector (Profs) 2 : Ajouter au (début, milieu ou fin) et Affichage de l ensemble 3 : Créer Dynamiquement 1 Element (Etud ou Prof) et Chercher s il existe (Sans utiliser le tri) 4 : Tri selon NOM et Affichage de l ensemble 5 : Tri selon Id et Affichage de l ensemble 6 : Quitter Le menu sera affiché via une fonction, les choix seront traités via l instruction case. Votre programme utilisera une série de fonctions permettant de séparer les tâches. Si nécessaire, des fonctions membres peuvent être ajoutées aux classes. On y prévoira au moins un constructeur par classe permettant, comme vu aux séances d exercices, l incrémentation automatique de l Id (Prof1 : Id=1, Prof2 : Id=2, et Etud1 : Id1=1, Etud2 : Id2=2,.). Optimisez votre code afin de permettre la réutilisation des morceaux de code.

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy Claude Delannoy Programmer en langage C++ 8 e édition Avec une intro aux design patterns et une annexe sur la norme C++11 Groupe Eyrolles, 1993-2011. Groupe Eyrolles, 2014, pour la nouvelle présentation,

Plus en détail

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère L'héritage et le polymorphisme en Java Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère En java, toutes les classes sont dérivée de la

Plus en détail

Généralités sur le Langage Java et éléments syntaxiques.

Généralités sur le Langage Java et éléments syntaxiques. Généralités sur le Langage Java et éléments syntaxiques. Généralités sur le Langage Java et éléments syntaxiques....1 Introduction...1 Genéralité sur le langage Java....1 Syntaxe de base du Langage...

Plus en détail

C++ COURS N 2 : CLASSES, DONNÉES ET FONCTIONS MEMBRES Classes et objets en C++ Membres d'une classe Spécification d'une classe Codage du comportement

C++ COURS N 2 : CLASSES, DONNÉES ET FONCTIONS MEMBRES Classes et objets en C++ Membres d'une classe Spécification d'une classe Codage du comportement C++ COURS N 2 : CLASSES, DONNÉES ET FONCTIONS MEMBRES Classes et objets en C++ Membres d'une classe Spécification d'une classe Codage du comportement des objets d'une classe Utilisation d'une classe Droit

Plus en détail

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile Dans ce TP, vous apprendrez à définir le type abstrait Pile, à le programmer en Java à l aide d une interface

Plus en détail

Chapitre 2. Classes et objets

Chapitre 2. Classes et objets Chapitre 2: Classes et Objets 1/10 Chapitre 2 Classes et objets Chapitre 2: Classes et Objets 2/10 Approche Orientée Objet Idée de base de A.O.O. repose sur l'observation de la façon dont nous procédons

Plus en détail

I. Introduction aux fonctions : les fonctions standards

I. Introduction aux fonctions : les fonctions standards Chapitre 3 : Les fonctions en C++ I. Introduction aux fonctions : les fonctions standards A. Notion de Fonction Imaginons que dans un programme, vous ayez besoin de calculer une racine carrée. Rappelons

Plus en détail

Premiers Pas en Programmation Objet : les Classes et les Objets

Premiers Pas en Programmation Objet : les Classes et les Objets Chapitre 2 Premiers Pas en Programmation Objet : les Classes et les Objets Dans la première partie de ce cours, nous avons appris à manipuler des objets de type simple : entiers, doubles, caractères, booléens.

Plus en détail

Cours d initiation à la programmation en C++ Johann Cuenin

Cours d initiation à la programmation en C++ Johann Cuenin Cours d initiation à la programmation en C++ Johann Cuenin 11 octobre 2014 2 Table des matières 1 Introduction 5 2 Bases de la programmation en C++ 7 3 Les types composés 9 3.1 Les tableaux.............................

Plus en détail

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java Langages objets Introduction M2 Pro CCI, Informatique Emmanuel Waller, LRI, Orsay présentation du module logistique 12 blocs de 4h + 1 bloc 2h = 50h 1h15 cours, 45mn exercices table, 2h TD machine page

Plus en détail

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation : Algorithmique et programmation : STRUCTURES DE DONNÉES A. Structure et enregistrement 1) Définition et rôle des structures de données en programmation 1.1) Définition : En informatique, une structure de

Plus en détail

Introduction à l héritage en C++

Introduction à l héritage en C++ Algorithmique/Langage 1ère année Introduction à l héritage en C++ Yacine BELLIK IUT d Orsay [email protected] 1 Bibliographie Ce cours est basé sur le livre suivant : Programmer en C++, 5ème édition

Plus en détail

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets. Encapsulation L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets. La visibilité dépend des membres : certains membres peuvent être visibles et d'autres

Plus en détail

Plan Pédagogique du cours

Plan Pédagogique du cours Plan Pédagogique du cours Module: Programmation Orientée Objet Section : informatique Niveau : 3 ème niveau (gestion, industriel, réseau) Volume Horaire : 22,5 heures Cours Intégrés + 45 Travaux Pratiques

Plus en détail

2 Grad Info Soir Langage C++ Juin 2007. Projet BANQUE

2 Grad Info Soir Langage C++ Juin 2007. Projet BANQUE 2 Grad Info Soir Langage C++ Juin 2007 Projet BANQUE 1. Explications L'examen comprend un projet à réaliser à domicile et à documenter : - structure des données, - objets utilisés, - relations de dépendance

Plus en détail

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004 Questionnaire d'examen final INF1101 Sigle du cours Nom : Signature : Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004 Professeur(s)

Plus en détail

Programmation C++ (débutant)/instructions for, while et do...while

Programmation C++ (débutant)/instructions for, while et do...while Programmation C++ (débutant)/instructions for, while et do...while 1 Programmation C++ (débutant)/instructions for, while et do...while Le cours du chapitre 4 : le for, while et do...while La notion de

Plus en détail

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP COURS PROGRAMMATION INITIATION AU LANGAGE C SUR MICROCONTROLEUR PIC page 1 / 7 INITIATION AU LANGAGE C SUR PIC DE MICROSHIP I. Historique du langage C 1972 : naissance du C dans les laboratoires BELL par

Plus en détail

Java Licence Professionnelle CISII, 2009-2010. Cours 2 : Classes et Objets

Java Licence Professionnelle CISII, 2009-2010. Cours 2 : Classes et Objets Licence Professionnelle CISII, 2009-2010 Cours 2 : Classes et Objets 1 Classes et Objets Objectifs des LOO : - Manipuler des objets - Découper les programmes suivant les types des objets manipulés - Regrouper

Plus en détail

Claude Delannoy. 3 e édition C++

Claude Delannoy. 3 e édition C++ Claude Delannoy 3 e édition Exercices Exercices C++ en en langage langage delc++ titre 4/07/07 15:19 Page 2 Exercices en langage C++ AUX EDITIONS EYROLLES Du même auteur C. Delannoy. Apprendre le C++.

Plus en détail

Polymorphisme, la classe Object, les package et la visibilité en Java... 1

Polymorphisme, la classe Object, les package et la visibilité en Java... 1 Polymorphisme, la classe Object, les package et la visibilité en Java. Polymorphisme, la classe Object, les package et la visibilité en Java.... 1 Polymorphisme.... 1 Le DownCast... 4 La Classe Object....

Plus en détail

Java Licence Professionnelle 2009-2010. Cours 7 : Classes et méthodes abstraites

Java Licence Professionnelle 2009-2010. Cours 7 : Classes et méthodes abstraites Java Licence Professionnelle 2009-2010 Cours 7 : Classes et méthodes abstraites 1 Java Classes et méthodes abstraites - Le mécanisme des classes abstraites permet de définir des comportements (méthodes)

Plus en détail

Programmation Orientée Objet en C#

Programmation Orientée Objet en C# Programmation Orientée Objet en C# 1 Introduction 1.1 Présentation Tout bon développeur le sait, le code d'un programme doit être propre, commenté, facile à maintenir et à améliorer. Vous êtes adepte de

Plus en détail

Héritage presque multiple en Java (1/2)

Héritage presque multiple en Java (1/2) Héritage presque multiple en Java (1/2) Utiliser deux classes ou plus dans la définition d'une nouvelle classe peut se faire par composition. class Etudiant{ int numero; Diplome d; float passeexamen(examen

Plus en détail

Travaux pratiques. Compression en codage de Huffman. 1.3. Organisation d un projet de programmation

Travaux pratiques. Compression en codage de Huffman. 1.3. Organisation d un projet de programmation Université de Savoie Module ETRS711 Travaux pratiques Compression en codage de Huffman 1. Organisation du projet 1.1. Objectifs Le but de ce projet est d'écrire un programme permettant de compresser des

Plus en détail

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1 Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1 B. Baert & F. Ludewig [email protected] - [email protected] Qu est-ce que la programmation? Programmer Ecrire un

Plus en détail

Licence ST Université Claude Bernard Lyon I LIF1 : Algorithmique et Programmation C Bases du langage C 1 Conclusion de la dernière fois Introduction de l algorithmique générale pour permettre de traiter

Plus en détail

Cours de C++ François Laroussinie. 2 novembre 2005. Dept. d Informatique, ENS de Cachan

Cours de C++ François Laroussinie. 2 novembre 2005. Dept. d Informatique, ENS de Cachan Cours de C++ François Laroussinie Dept. d Informatique, ENS de Cachan 2 novembre 2005 Première partie I Introduction Introduction Introduction Algorithme et programmation Algorithme: méthode pour résoudre

Plus en détail

Chap III : Les tableaux

Chap III : Les tableaux Chap III : Les tableaux Dans cette partie, on va étudier quelques structures de données de base tels que : Les tableaux (vecteur et matrice) Les chaînes de caractères LA STRUCTURE DE TABLEAU Introduction

Plus en détail

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40 Déroulement du cours Introduction Concepts Java Remarques Langage et Concepts de Programmation Orientée-Objet Gauthier Picard École Nationale Supérieure des Mines de Saint-Étienne [email protected]

Plus en détail

Algorithmique et Programmation, IMA

Algorithmique et Programmation, IMA Algorithmique et Programmation, IMA Cours 2 : C Premier Niveau / Algorithmique Université Lille 1 - Polytech Lille Notations, identificateurs Variables et Types de base Expressions Constantes Instructions

Plus en détail

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski [email protected]

Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski cegielski@u-pec.fr Introduction à la programmation orientée objet, illustrée par le langage C++ Patrick Cégielski [email protected] Mars 2002 Pour Irène et Marie Legal Notice Copyright c 2002 Patrick Cégielski Université

Plus en détail

Les structures de données. Rajae El Ouazzani

Les structures de données. Rajae El Ouazzani Les structures de données Rajae El Ouazzani Les arbres 2 1- Définition de l arborescence Une arborescence est une collection de nœuds reliés entre eux par des arcs. La collection peut être vide, cad l

Plus en détail

Cours 1: Java et les objets

Cours 1: Java et les objets Ressources Les interface homme-machine et le langage Java DUT première année Henri Garreta, Faculté des Sciences (Luminy) Cyril Pain-Barre & Sébastien Nedjar, IUT d Aix-Marseille (Aix) Cours 1: infodoc.iut.univ-aix.fr/~ihm/

Plus en détail

Diagramme de classes

Diagramme de classes Diagramme de classes Un diagramme de classes décrit les classes et leurs relations (associations, généralisation/spécialisation, ). classe association méthodes attributs héritage Diagramme de classes :

Plus en détail

1.6- Génération de nombres aléatoires

1.6- Génération de nombres aléatoires 1.6- Génération de nombres aléatoires 1- Le générateur aléatoire disponible en C++ 2 Création d'un générateur aléatoire uniforme sur un intervalle 3- Génération de valeurs aléatoires selon une loi normale

Plus en détail

Bernard HAMM, Évelyne LAVOISIER

Bernard HAMM, Évelyne LAVOISIER 92 MAÎTRISE DE PROGICIELS DE GESTION DE BASES DE DONNÉES ET DE TRAITEMENT DE TEXTE Compte rendu d'un stage à l'usage des professeurs de sciences sociales. Ce stage a été programmé A la demande et avec

Plus en détail

LibreOffice Calc : introduction aux tableaux croisés dynamiques

LibreOffice Calc : introduction aux tableaux croisés dynamiques Fiche logiciel LibreOffice Calc 3.x Tableur Niveau LibreOffice Calc : introduction aux tableaux croisés dynamiques Un tableau croisé dynamique (appelé Pilote de données dans LibreOffice) est un tableau

Plus en détail

Génie Logiciel I. Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string

Génie Logiciel I. Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string Génie Logiciel I Cours VI - Typage statique / dynamique, fonctions virtuelles et classes abstraites, flots d entrées / sorties, et string Nicolas Kielbasiewicz C.D.C.S.P./I.S.T.I.L./I.C.J. Filière M.A.M.

Plus en détail

Initiation à JAVA et à la programmation objet. [email protected]

Initiation à JAVA et à la programmation objet. raphael.bolze@ens-lyon.fr Initiation à JAVA et à la programmation objet [email protected] O b j e c t i f s Découvrir un langage de programmation objet. Découvrir l'environnement java Découvrir les concepts de la programmation

Plus en détail

1. Qu'est-ce que SQL?... 2. 2. La maintenance des bases de données... 2. 3. Les manipulations des bases de données... 5

1. Qu'est-ce que SQL?... 2. 2. La maintenance des bases de données... 2. 3. Les manipulations des bases de données... 5 1. Qu'est-ce que SQL?... 2 2. La maintenance des bases de données... 2 2.1 La commande CREATE TABLE... 3 2.2 La commande ALTER TABLE... 4 2.3 La commande CREATE INDEX... 4 3. Les manipulations des bases

Plus en détail

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu. Seance 2: Complétion du code de jeu. (durée max: 2h) Mot clé const et pointeurs: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu. Implémentez jeu_recupere_piece

Plus en détail

COMPARAISONDESLANGAGESC, C++, JAVA ET

COMPARAISONDESLANGAGESC, C++, JAVA ET REPUBLIQUE DU BENIN *******@******* MINISTERE DE L ENSEIGNEMENT SUPERIEUR ET DE LA RECHERCHE SCIENTIFIQUE(MESRS) *******@******* UNIVERSITE D ABOMEY CALAVI(UAC) *******@******* ECOLE POLYTECHNIQUE D ABPOMEY

Plus en détail

Le langage C. Séance n 4

Le langage C. Séance n 4 Université Paris-Sud 11 Institut de Formation des Ingénieurs Remise à niveau INFORMATIQUE Année 2007-2008 Travaux pratiques d informatique Le langage C Séance n 4 But : Vous devez maîtriser à la fin de

Plus en détail

Automatisation d'une Facture 4. Liste Déroulante Remises Case à cocher Calculs

Automatisation d'une Facture 4. Liste Déroulante Remises Case à cocher Calculs Dans la série Les tutoriels libres présentés par le site FRAMASOFT Automatisation d'une Facture 4 Liste Déroulante Remises Case à cocher Calculs Logiciel: Version: Licence: Site: OpenOffice.org Calc :

Plus en détail

Cours Programmation Système

Cours Programmation Système Cours Programmation Système Filière SMI Semestre S6 El Mostafa DAOUDI Département de Mathématiques et d Informatique, Faculté des Sciences Université Mohammed Premier Oujda [email protected] Février

Plus en détail

Programmation Objet - Cours II

Programmation Objet - Cours II Programmation Objet - Cours II - Exercices - Page 1 Programmation Objet - Cours II Exercices Auteur : E.Thirion - Dernière mise à jour : 05/07/2015 Les exercices suivants sont en majorité des projets à

Plus en détail

Programmer en JAVA. par Tama ([email protected]( [email protected])

Programmer en JAVA. par Tama (tama@via.ecp.fr( tama@via.ecp.fr) Programmer en JAVA par Tama ([email protected]( [email protected]) Plan 1. Présentation de Java 2. Les bases du langage 3. Concepts avancés 4. Documentation 5. Index des mots-clés 6. Les erreurs fréquentes

Plus en détail

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie Chapitre I : Les bases du C++ Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie du logiciel, et ce depuis

Plus en détail

Programmation par les Objets en Java

Programmation par les Objets en Java Programmation par les Objets en Java Najib TOUNSI Les classes en Java (TD 3) I. Notion de classe I.1 Classe, champs, méthodes, instanciation, this, private vs. public. Créer une classe Point (coordonnée

Plus en détail

Une introduction à Java

Une introduction à Java Une introduction à Java IFT 287 (Semaine 1) UNIVERSITÉ DE SHERBROOKE 1 Java - Historique Développé par Sun Microsystems en 1994 Inventeur James Gosling (canadien!) Objectif langage sûr (fortement typé)

Plus en détail

Recherche dans un tableau

Recherche dans un tableau Chapitre 3 Recherche dans un tableau 3.1 Introduction 3.1.1 Tranche On appelle tranche de tableau, la donnée d'un tableau t et de deux indices a et b. On note cette tranche t.(a..b). Exemple 3.1 : 3 6

Plus en détail

Initiation à la programmation en Python

Initiation à la programmation en Python I-Conventions Initiation à la programmation en Python Nom : Prénom : Une commande Python sera écrite en caractère gras. Exemples : print 'Bonjour' max=input("nombre maximum autorisé :") Le résultat de

Plus en détail

Bases de programmation. Cours 5. Structurer les données

Bases de programmation. Cours 5. Structurer les données Bases de programmation. Cours 5. Structurer les données Pierre Boudes 1 er décembre 2014 This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License. Types char et

Plus en détail

1. Introduction...2. 2. Création d'une requête...2

1. Introduction...2. 2. Création d'une requête...2 1. Introduction...2 2. Création d'une requête...2 3. Définition des critères de sélection...5 3.1 Opérateurs...5 3.2 Les Fonctions...6 3.3 Plusieurs critères portant sur des champs différents...7 3.4 Requête

Plus en détail

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre 2009. [email protected]

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre 2009. Enrica.Duchi@liafa.jussieu.fr . Cours intensif Java 1er cours: de C à Java Septembre 2009 Enrica DUCHI LIAFA, Paris 7 [email protected] LANGAGES DE PROGRAMMATION Pour exécuter un algorithme sur un ordinateur il faut le

Plus en détail

Programmation en Java IUT GEII (MC-II1) 1

Programmation en Java IUT GEII (MC-II1) 1 Programmation en Java IUT GEII (MC-II1) 1 Christophe BLANC - Paul CHECCHIN IUT Montluçon Université Blaise Pascal Novembre 2009 Christophe BLANC - Paul CHECCHIN Programmation en Java IUT GEII (MC-II1)

Plus en détail

Java Licence Professionnelle CISII, 2009-10

Java Licence Professionnelle CISII, 2009-10 Java Licence Professionnelle CISII, 2009-10 Cours 4 : Programmation structurée (c) http://www.loria.fr/~tabbone/cours.html 1 Principe - Les méthodes sont structurées en blocs par les structures de la programmation

Plus en détail

TP1 : Initiation à Java et Eclipse

TP1 : Initiation à Java et Eclipse TP1 : Initiation à Java et Eclipse 1 TP1 : Initiation à Java et Eclipse Systèmes d Exploitation Avancés I. Objectifs du TP Ce TP est une introduction au langage Java. Il vous permettra de comprendre les

Plus en détail

Cours de Programmation Impérative: Zones de mémoires et pointeurs

Cours de Programmation Impérative: Zones de mémoires et pointeurs Cours de Programmation Impérative: Zones de mémoires et pointeurs Julien David A101 - [email protected] Julien David (A101 - [email protected]) 1 / 1 Z`o n`e s `d`e m`é m`o i r`e Julien

Plus en détail

Java 7 Les fondamentaux du langage Java

Java 7 Les fondamentaux du langage Java 184 Java 7 Les fondamentaux du langage Java 1.1 Les bibliothèques graphiques Le langage Java propose deux bibliothèques dédiées à la conception d'interfaces graphiques. La bibliothèque AWT et la bibliothèque

Plus en détail

SHERLOCK 7. Version 1.2.0 du 01/09/09 JAVASCRIPT 1.5

SHERLOCK 7. Version 1.2.0 du 01/09/09 JAVASCRIPT 1.5 SHERLOCK 7 Version 1.2.0 du 01/09/09 JAVASCRIPT 1.5 Cette note montre comment intégrer un script Java dans une investigation Sherlock et les différents aspects de Java script. S T E M M E R I M A G I N

Plus en détail

Cours d Algorithmique et de Langage C 2005 - v 3.0

Cours d Algorithmique et de Langage C 2005 - v 3.0 Cours d Algorithmique et de Langage C 2005 - v 3.0 Bob CORDEAU [email protected] Mesures Physiques IUT d Orsay 15 mai 2006 Avant-propos Avant-propos Ce cours en libre accès repose sur trois partis pris

Plus en détail

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE 2 ème partie : REQUÊTES Sommaire 1. Les REQUÊTES...2 1.1 Créer une requête simple...2 1.1.1 Requête de création de listage ouvrages...2 1.1.2 Procédure de

Plus en détail

Le modèle de données

Le modèle de données Le modèle de données Introduction : Une fois que l étude des besoins est complétée, deux points importants sont à retenir : Les données du système étudié Les traitements effectués par le système documentaire.

Plus en détail

Conventions d écriture et outils de mise au point

Conventions d écriture et outils de mise au point Logiciel de base Première année par alternance Responsable : Christophe Rippert [email protected] Introduction Conventions d écriture et outils de mise au point On va utiliser dans cette

Plus en détail

Travaux Dirigés n 1 : chaînes de caractères

Travaux Dirigés n 1 : chaînes de caractères UE LE315 Travaux Dirigés n 1 : chaînes de caractères Exercice 1 Ecrire une fonction int nombre_caract(char *chaîne) qui retourne la taille d une chaîne de caractères. Exercice 2 Ecrire la fonction void

Plus en détail

UML et les Bases de Données

UML et les Bases de Données CNAM UML et les Bases de Données UML et les Bases de Données. Diagramme de classes / diagramme d objets (UML)...2.. Premier niveau de modélisation des données d une application...2.2. Les éléments de modélisation...2.2..

Plus en détail

Les chaînes de caractères

Les chaînes de caractères Les chaînes de caractères Dans un programme informatique, les chaînes de caractères servent à stocker les informations non numériques comme par exemple une liste de nom de personne ou des adresses. Il

Plus en détail

les Formulaires / Sous-Formulaires Présentation...2 1. Créer un formulaire à partir d une table...3

les Formulaires / Sous-Formulaires Présentation...2 1. Créer un formulaire à partir d une table...3 Présentation...2 1. Créer un formulaire à partir d une table...3 2. Les contrôles :...10 2.1 Le contrôle "Intitulé"...11 2.2 Le contrôle "Zone de Texte"...12 2.3 Le contrôle «Groupe d options»...14 2.4

Plus en détail

as Architecture des Systèmes d Information

as Architecture des Systèmes d Information Plan Plan Programmation - Introduction - Nicolas Malandain March 14, 2005 Introduction à Java 1 Introduction Présentation Caractéristiques Le langage Java 2 Types et Variables Types simples Types complexes

Plus en détail

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 )

P r ob lé m a t iq u e d e la g é n é r icit é. Pr in cip e d e la g é n é r icit é e n Ja v a ( 1 /3 ) P r ob lé m a t iq u e d e la g é n é r icit é les versions de Java antérieures à 1.5 permettaient de créer des classes de structures contenant n'importe quels types d'objet : les collections (classes

Plus en détail

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java Info0101 Intro. à l'algorithmique et à la programmation Cours 3 Le langage Java Pierre Delisle, Cyril Rabat et Christophe Jaillet Université de Reims Champagne-Ardenne Département de Mathématiques et Informatique

Plus en détail

"! "#$ $ $ ""! %#& """! '& ( ")! )*+

! #$ $ $ ! %#& ! '& ( )! )*+ ! "! "#$ $ $ ""! %#& """! '& ( ")! )*+ "! "#$ $ $ ""! %#& """! '& ( ")! )*+, ## $ *$-./ 0 - ## 1( $. - (/$ #,-".2 + -".234-5..'"6..6 $37 89-%:56.#&(#. +6$../.4. ;-37 /. .?.@A&.!)B

Plus en détail

UE C avancé cours 1: introduction et révisions

UE C avancé cours 1: introduction et révisions Introduction Types Structures de contrôle Exemple UE C avancé cours 1: introduction et révisions Jean-Lou Desbarbieux et Stéphane Doncieux UMPC 2004/2005 Introduction Types Structures de contrôle Exemple

Plus en détail

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml OCL Object Constraint Language Le langage de contraintes d'uml Plan 1. Introduction 2. Les principaux concepts d'ocl Object Constraint Language 1 Object Constraint Language 2 Exemple: une application bancaire

Plus en détail

EXCEL TUTORIEL 2012/2013

EXCEL TUTORIEL 2012/2013 EXCEL TUTORIEL 2012/2013 Excel est un tableur, c est-à-dire un logiciel de gestion de tableaux. Il permet de réaliser des calculs avec des valeurs numériques, mais aussi avec des dates et des textes. Ainsi

Plus en détail

GOL502 Industries de services

GOL502 Industries de services GOL502 Industries de services Conception d un service Partie IIb Version 2013 Introduction Conception d un service partie IIb Nous verrons dans ce chapitre Modélisation d un service; Langage de modélisation

Plus en détail

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai. Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai. 1 Introduction On considère une grille de 20 lignes 20 colonnes. Une case de la grille peut être vide, ou contenir une et une

Plus en détail

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ; CNAM NFP121 TP 10 19/11/2013 (Séance 5) Objectif Manipuler les exceptions ; 1 Entrées/sorties Exercice 1 : Lire un entier à partir du clavier Ajouter une méthode readint(string message) dans la classe

Plus en détail

Traduction des Langages : Le Compilateur Micro Java

Traduction des Langages : Le Compilateur Micro Java BARABZAN Jean-René OUAHAB Karim TUCITO David 2A IMA Traduction des Langages : Le Compilateur Micro Java µ Page 1 Introduction Le but de ce projet est d écrire en JAVA un compilateur Micro-Java générant

Plus en détail

modélisation solide et dessin technique

modélisation solide et dessin technique CHAPITRE 1 modélisation solide et dessin technique Les sciences graphiques regroupent un ensemble de techniques graphiques utilisées quotidiennement par les ingénieurs pour exprimer des idées, concevoir

Plus en détail

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3. 1. Structure d un programme C Un programme est un ensemble de fonctions. La fonction "main" constitue le point d entrée pour l exécution. Un exemple simple : #include int main() { printf ( this

Plus en détail

Publipostage avec Calc

Publipostage avec Calc Auto-formation sur OpenOffice.org 2.0 par Cyril Beaussier Version 1.0.2 - Avril 2006 Publipostage avec Calc Sommaire Introduction... 2 Présentation... 3 Notions... 4 Les données... 5 Lettre type... 7 Création

Plus en détail

Présentation du langage et premières fonctions

Présentation du langage et premières fonctions 1 Présentation de l interface logicielle Si les langages de haut niveau sont nombreux, nous allons travaillé cette année avec le langage Python, un langage de programmation très en vue sur internet en

Plus en détail

Introduction à MATLAB R

Introduction à MATLAB R Introduction à MATLAB R Romain Tavenard 10 septembre 2009 MATLAB R est un environnement de calcul numérique propriétaire orienté vers le calcul matriciel. Il se compose d un langage de programmation, d

Plus en détail

Les structures. Chapitre 3

Les structures. Chapitre 3 Chapitre 3 Les structures Nous continuons notre étude des structures de données qui sont prédéfinies dans la plupart des langages informatiques. La structure de tableau permet de regrouper un certain nombre

Plus en détail

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation impérative et structures de données simples Introduction au langage C Sandrine Blazy - 1ère année 24 octobre 2007 Cours d Algorithmique-Programmation

Plus en détail

INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX

INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX TABLE DES MATIERES Livret Utilisateur Excel 2007 Niveau 2 INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX... 4 Les tableaux croisés dynamiques... 4 Création d un tableau croisé... 5 Comparer des

Plus en détail

Création d objet imbriqué sous PowerShell.

Création d objet imbriqué sous PowerShell. Création d objet imbriqué sous PowerShell. Par Laurent Dardenne, le 13/01/2014. Niveau Ce tutoriel aborde la création d objet composé, c est-à-dire que certains de ses membres seront eux-mêmes des PSObjects.

Plus en détail

Exercices INF5171 : série #3 (Automne 2012)

Exercices INF5171 : série #3 (Automne 2012) Exercices INF5171 : série #3 (Automne 2012) 1. Un moniteur pour gérer des ressources Le moniteur MPD 1 présente une première version d'un moniteur, exprimé en pseudo-mpd, pour gérer des ressources le nombre

Plus en détail

INFO-F-105 Language de programmation I Séance VI

INFO-F-105 Language de programmation I Séance VI INFO-F-105 Language de programmation I Séance VI Jérôme Dossogne Année académique 2008 2009 Un grand merci à Yves Roggeman pour ses relectures et remarques des codes et commentaires qui ont contribuées

Plus en détail

Langage Java. Classe de première SI

Langage Java. Classe de première SI Langage Java Table des matières 1. Premiers pas...2 1.1. Introduction...2 1.2. Mon premier programme...2 1.3. Les commentaires...2 2. Les variables et les opérateurs...2 3. La classe Scanner...3 4. Les

Plus en détail

LE LANGAGE C++ ENAC 1997 A. DANCEL

LE LANGAGE C++ ENAC 1997 A. DANCEL LE LANGAGE C++ ENAC 1997 A. DANCEL 1 - GENERALITES "L'homme se découvre quand il se mesure avec l'objet." Antoine de Saint-Exupéry, Terre des hommes 1.1 INTRODUCTION Ce cours est conçu pour permettre aux

Plus en détail

UE Programmation Impérative Licence 2ème Année 2014 2015

UE Programmation Impérative Licence 2ème Année 2014 2015 UE Programmation Impérative Licence 2 ème Année 2014 2015 Informations pratiques Équipe Pédagogique Florence Cloppet Neilze Dorta Nicolas Loménie [email protected] 2 Programmation Impérative

Plus en détail

TD/TP PAC - Programmation n 3

TD/TP PAC - Programmation n 3 Université Paris Sud Licence d informatique/iup-miage2 Année 2004-2005 Auteur : Frédéric Vernier Semaine : 11-16 octobre 2004 Conditions : sur machine avec les outils standards java web: http://vernier.frederic.free.fr/indexpac.html

Plus en détail

Chapitre 10. Les interfaces Comparable et Comparator 1

Chapitre 10. Les interfaces Comparable et Comparator 1 Chapitre 10: Les interfaces Comparable et Comparator 1/5 Chapitre 10 Les interfaces Comparable et Comparator 1 1 Ce chapitre a été extrait du document "Objets, Algorithmes, Patterns" de [René Lalement],

Plus en détail

Chapitre 2 Le problème de l unicité des solutions

Chapitre 2 Le problème de l unicité des solutions Université Joseph Fourier UE MAT 127 Mathématiques année 2011-2012 Chapitre 2 Le problème de l unicité des solutions Ce que nous verrons dans ce chapitre : un exemple d équation différentielle y = f(y)

Plus en détail

Génie Logiciel avec Ada. 4 février 2013

Génie Logiciel avec Ada. 4 février 2013 Génie Logiciel 4 février 2013 Plan I. Généralités II. Structures linéaires III. Exceptions IV. Structures arborescentes V. Dictionnaires I. Principes II. Notions propres à la POO I. Principes Chapitre

Plus en détail

Université de Bangui. Modélisons en UML

Université de Bangui. Modélisons en UML Université de Bangui CRM Modélisons en UML Ce cours a été possible grâce à l initiative d Apollinaire MOLAYE qui m a contacté pour vous faire bénéficier de mes connaissances en nouvelles technologies et

Plus en détail