Chapitre III Introduction aux objets et aux classes
Chapitre III - Introduction aux objets et aux classes2 Introduction au concept d’objet Supposons que Luc veuille se procurer du bois de chauffage pour l’hiver prochain. Luc habite dans un centre-ville. Aller couper du bois en forêt est hors de question. Luc va alors chez son voisin qui lui donne le numéro de téléphone d’un fournisseur Gilles. Luc lance une commande à ce fournisseur et lui donne son adresse. Luc peut être sûr que le bois sera expédié dans les délais à l’endroit voulu.
Chapitre III - Introduction aux objets et aux classes3 Introduction au concept d’objet Luc a solutionné son problème en choisissant un objet [Gilles, le fournisseur] et lui a transmis un message contenant sa requête [livrer du bois de chauffage à l’adresse de son domicile]. C’est la responsabilité de Gilles de répondre à la requête de Luc. Gilles connaît et utilise des méthodes qui lui appartiennent pour répondre à la demande. Les mécanismes et les moyens employés pour livrer le bois de chauffage sont inconnus de Luc (encapsulation). Luc n’a pas à connaître la façon exacte dont sera exécutée sa commande, l’important étant que le bois de chauffage soit livré à son domicile dans les délais.
Chapitre III - Introduction aux objets et aux classes4 Introduction au concept d’objet L’objet Luc envoie le message : expédier(type de bois de chauffage, quantité de bois, adresse de destination) à un autre objet Gilles. L’interprétation du message dépend de l’objet « récepteur ». Le message peut ne pas être compris : « type de bois de chauffage ? » Un objet a un ensemble de responsabilités dont il est le dépositaire, ce qui correspond aux messages ou requêtes qu’il peut comprendre et exécuter. PROTOCOLE INTERFACE ensemble des responsabilités d’un objet
Chapitre III - Introduction aux objets et aux classes5 Introduction au concept d’objet Lorsqu’on communique avec Gilles, on s’attend à obtenir certains services de sa part parce qu’on connaît ce qu’un tel fournisseur en général peut offrir comme services. On peut dire que Gilles est une instance de la classe Fournisseur en bois. Les objets sont des instances d’une classe. Tous les objets d’une classe donnée utilisent la même méthode en réponse à des messages identiques.
Chapitre III - Introduction aux objets et aux classes6 Intérêt du concept d’objet Développer des programmes informatiques consiste à gérer des données et des traitements. Dans un langage comme C, les données sont symbolisées par des variables souvent regroupées dans des structures alors que les traitements sont identifiés par des fonctions. Les fonctions qui servent à manipuler ces structures doivent posséder un lien vers l ’enregistrement à traiter (pointeur, valeur). Ces liens sont nécessaires dans un langage comme C parce que d ’entité regroupant à la fois variables & fonctions. Un objet est justement une entité qui renferme à la fois des variables et des fonctions.
Différences entre les concepts de classe & objet Classe Représente un type de données abstrait. Représente un gabarit (une abstraction) permettant de créer des variables que l ’on appelle objets (ou instances de classes) Regroupe tous les comportements (fonctions) & tous les attributs (données) d ’une famille d ’objets. Définit les opérations qui sont permises sur les objets de la classe. Définit les états que les objets peuvent prendre.
Chapitre III - Introduction aux objets et aux classes8 Différences entre les concepts de classe & objet Objet Possède ses propres attributs qui lui permettent de se différencier des autres objets de la même classe. En C++, ces données sont appelées des données membres. Les fonctions membres définissent l’ensemble des tâches et opérations qu’il est possible de mettre en œuvre avec cet objet. Ils permettent de préciser le comportement d’une classe.
Chapitre III - Introduction aux objets et aux classes9 Notion d’objet Un objet a un état, un comportement et une identité unique. La structure et le comportement d’objets semblables sont définis dans la classe qui leur est commune. INSTANCE OCCURRENCE OBJET ÉTAT d’un objet valeurs des attributs de l’objet COMPORTEMENT d’un objet ensemble des opérations qu’on peut effectuer sur celui-ci. IDENTITÉ d’un objet 2 objets peuvent avoir le même état mais toujours une identité unique.Ex. : une adresse en mémoire.
Chapitre III - Introduction aux objets et aux classes10 Exemple d’une classe « livre » Données membres - Cote - Auteur(s) - Année de parution - Maison d’édition - etc. Fonctions membres - Acheter - Réserver - Commander
Chapitre III - Introduction aux objets et aux classes11 Exemple d’un objet de la classe « livre » Données membres - A Stéphane Dupin Campus Press - etc. Fonctions membres - Ce livre peut être acheté, réservé ou commandé dans une librairie de votre choix.
Chapitre III - Introduction aux objets et aux classes12 Encapsulation & système de protection La classe est responsable d’assurer la validité de tous les objets créés à partir d’elle-même. Un objet doit être valide de la création jusqu’à sa destruction. Encapsulation : Principe qui permet de regrouper les données et les fonctions au sein d ’une classe. Cette notion est associée à un système de protection contrôlant la visibilité d’une variable ou d’une fonction membre. Pour indiquer les droits d’accès à l’utilisation des membres d ’une classe, C++ propose 3 niveaux de protections. Les données ou fonctions membres d ’une classe définies avec le mot clé suivant sont utilisables : Mot clé public:par toutes les fonctions Mot clé private:uniquement par les fonctions membres de cette classe Mot clé protected: uniquement par les fonctions membres de cette classe et celles des classes dérivées.
Chapitre III - Introduction aux objets et aux classes13 Encapsulation & système de protection À moins d’avis contraire, nous utiliserons le niveau de protection private pour les données membres et public pour les fonctions membres. Avec l’encapsulation, pas de données globales. Permet de résoudre le problème de couplage des données dans l’approche procédurale. Permet de masquer les détails d’implantation à l’intérieur de la classe. Les interactions avec les autres objets se font en passant par l’interface de chaque classe définie à cet effet. Ces objets n’ont pas la possibilité de connaître comment la classe est implanté, ces détails étant cachés à l’intérieur de la classe elle-même. On ne peut modifier l’état d’un objet directement, on passe par l’interface. L’interface contient les déclarations de toutes les opérations applicables sur les instances de cette classe.
14 Définition d ’une classe Pour définir une classe, utilisez le mot clé « class » en respectant la syntaxe suivante: class Nom_de_classe { private : // déclaration des données membres public : // déclaration des fonctions membres publiques }; Les étiquettes private et public ne constituent pas une obligation mais plutôt une règle de conduite. Une interface correspond à la liste des fonctions membres publiques qui sont donc accessibles aux utilisateurs d’une classe. Définir l’implantation des fonctions membres après la définition de la classe dans un fichier séparé. Erreur classique : Oubli d’un point-virgule.
15 Fonctions utilitaires dans une classe Toutes les fonctions membres ne requièrent pas nécessairement une décla- ration public pour remplir leur rôle de composant de l’interface d’une classe. Certaines fonctions demeurent private et servent de fonctions utilitaires pour les autres fonctions de la classe (un support aux opérations des fonctions publiques de la classe). Les fonctions utilitaires ne sont pas conçues pour être employées par les clients d’une classe. Exemple : La classe « Representant_des_ventes » renferme : - un tableau de 12 montants des ventes mensuelles - un interface : une fonction d’initialisation du tableau, la réception d’une vente et l’affichage des ventes annuelles totales - une fonction utilitaire : calcul des ventes totales annuelles. utilise
Chapitre III - Introduction aux objets et aux classes16 Déclaration des données membres d ’une classe Les données membres sont les variables définies à l’intérieur d’une classe. La portée de ces variables doit être précisée : public, private ou protected. Exemple :class Etudiant { private : int matricule; char nom[20 +1], prenom[20 + 1]; float moyenne_cumulative; }; La syntaxe est très proche de celle des structures. Cela n ’entraîne pas de réservation mémoire; cela sera effectif lors de la création d’objets de cette classe.
17 Déclaration des fonctions membres d’une classe Les fonctions membres correspondent aux fonctions que vous définissez au sein de la classe. Ils représentent l’ensemble des traitements que vous pouvez mettre en œuvre sur les données membres de la classe. MÉTHODESFONCTIONS MEMBRES 2 techniques différentes pour créer des fonctions membres: -fonctions inline :(à venir) l ’appel de la fonction remplacé par le corps de la fonction. -la définition déportée : (approche usuelle) définir le prototype de la fonction à l ’intérieur de la classe, définir le corps de la fonction en dehors de cette classe en utilisant le nom complet de la méthode (bonne pratique permettant de séparer l’interface de la classe et son implantation).
Chapitre III - Introduction aux objets et aux classes18 Déclaration des fonctions membres d’une classe Exemple : class Etudiant { private : int matricule; float moyenne_cumulative; public : void Inserer_Matricule(int Mat); void Inserer_Moyenne_cumulative(float Mc); void Affiche(); };
Chapitre III - Introduction aux objets et aux classes19 Déclaration des fonctions membres d’une classe Exemple : (suite) void Etudiant::Affiche() { cout << " Matricule : " << matricule; cout << " Moyenne cumulative : " << moyenne_cumulative; } void Etudiant::Inserer_Matricule(int Mat) { matricule = Mat; } void Etudiant::Inserer_Moyenne_cumulative(float Mc) { moyenne_cumulative = Mc; }
Chapitre III - Introduction aux objets et aux classes20 Déclaration des fonctions membres d’une classe Commentaires portant sur l’exemple précédent : -L ’opérateur :: s’appelle l ’Opérateur de Résolution de Portée (ORP). Exemple :L ’expression Etudiant::Inserer_Matricule identifie de cette manière la fonction membre Inserer_Matricule de la classe. -Cette syntaxe permet au compilateur d ’identifier une fonction membre par rapport aux fonctions n ’appartenant pas à une classe. Une fonction Affiche() n ’appartenant à aucune classe ou appartenant à d’autres classes peut être défini dans le même fichier source. À l ’intérieur du corps d’une fonction membre, il n’est pas nécessaire de faire référence à un objet pour manipuler les variables ou les autres fonctions membres de la classe.
Chapitre III - Introduction aux objets et aux classes21 Déclaration des fonctions membres d’une classe Remarque : Bien qu’une fonction membre soit définie en dehors de la définition de sa classe, comme cette fonction membre est déclarée à l’intérieur de la classe, elle demeure toujours sous la portée de cette classe. Son nom n’est connu qu’aux autres membres de la classe, à moins qu’une référence via un objet de cette classe (l’opérateur point), qu’un pointeur vers un objet de cette classe n’en assure l’accès.
Chapitre III - Introduction aux objets et aux classes22 Création d ’objets Une classe est un type de données qui n’a qu’un seul objectif : permettre la création d’objets. Deux solutions pour créer les objets: -la création statique -la création dynamique Création statique : syntaxe habituelle pour créer des variables d ’un certain type. Exemple :Etudiant E; La variable E correspond à un objet de type Etudiant que vous pouvez utiliser pour accéder aux données et fonctions membres de la classe.
Chapitre III - Introduction aux objets et aux classes23 Création d’objets Création dynamique : 3 étapes à suivre:(A)définir un pointeur vers la classe, (B)utiliser l’opérateur new; (C)détruire l’objet après son utilisation. (A)La manipulation d’un objet se fait à l’aide d’un pointeur; nous ne disposons pas du nom d’un objet. Etudiant * pE; Le pointeur pE peut être utilisé pour stocker l’adresse d’un objet de type Etudiant. (B)L ’opérateur new est utilisé pour créer un objet de la classe Etudiant : pE = new Etudiant; Il renvoie l’adresse de l’objet créé permettant d’initialiser pE. pE donne alors accès aux membres de la classe Etudiant.
Chapitre III - Introduction aux objets et aux classes24 Création d’objets Création dynamique : (suite) (C)Détruire les objets après les avoir utilisés : l ’opérateur delete. delete pE; Pour utiliser l’opérateur delete, vous devez fournir le pointeur vers l’objet à détruire. En cas d’omission, votre programme ne libérera pas toute la mémoire utilisée par ces objets. Une fois détruit, le pointeur est initialisé avec la constante NULL. Les objets statiques sont détruits automatiquement dès que le programme quitte la portée où ils ont été créés.
Chapitre III - Introduction aux objets et aux classes25 Création d’objets C++ comme langage extensible Une fois la classe définie, elle peut intervenir dans des déclarations de la même façon que tout autre type : Etudiant X,// Objet de type Etudiant Classe[25],// Tableau d’objets Etudiant *pY,// Pointeur vers un objet Etudiant &Z = X;// Référence à un objet Etudiant Le nom de la classe devient un nouvel identificateur de type et peut engendrer de nombreux objets, de la même manière que de nombreuses variables peuvent être bâties sur un type tel que int.
Chapitre III - Introduction aux objets et aux classes26 Accès aux membres d’une classe Après avoir créé un objet, vous pouvez accéder à ses données et fonctions membres. La syntaxe est la même que celle que vous avez déjà employée pour accéder aux champs d’une structure c’est-à-dire, -le point (‘. ’) dans le cas d’un objet créé en statique, -la flèche (‘ -> ’) dans le cas d ’un objet créé en dynamique. Exemple à partir de la classe Etudiant :(cas d’un objet statique) int main() { Etudiant E; E.Inserer_Matricule(98123);// E.matricule = 98123; cause une erreur. E.Inserer_Moyenne_cumulative(3.76); E.Affiche(); return 0; }
Chapitre III - Introduction aux objets et aux classes27 Accès aux membres d’une classe Exemple à partir de la classe Etudiant :(cas d ’un objet dynamique) int main() { Etudiant * pE; pE = new Etudiant; pE->Inserer_Matricule(98123); // pE->matricule = 98123; cause une erreur. pE->Inserer_Moyenne_cumulative(3.76); pE->Affiche(); delete pE; return 0; }
Chapitre III - Introduction aux objets et aux classes28 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.h » class Chaine_de_lettres { /*Spécification fonctionnelle de la classe " Chaîne_de_lettres " Composantes :Les composantes de ce type de donnée sont les caractères 'a'-'z', 'A'-'Z' et le caractère espace lesquels sont appelés lettres. Structure :Il existe une relation linéaire (structure) entre les composantes d'une chaîne de lettres. Domaine :Cela renferme l'ensemble des chaînes de lettres dont la longueur est entre 0 et 80 lettres. */
Chapitre III - Introduction aux objets et aux classes29 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.h » (suite) private: int n;/* Longueur de la chaîne*/ char chaine[80+1];/* Chaîne de lettres*/ public: void Creer_chaine_vide(); /*Permet de créer une chaîne vide. Pré -Nil. Post -La chaîne de lettres est de longueur 0.*/
Chapitre III - Introduction aux objets et aux classes30 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.h » (suite) char Extraire_lettre_la_plus_a_gauche(); /*Extraire de la chaîne de lettres la lettre la plus à gauche et fournir celle-ci comme résultat. Pré -La chaîne de lettres a déjà été créée et sa longueur est > 0. Post -Extrait et fournit la lettre la plus à gauche de la chaîne. */ void Concatener_lettre_a_chaine(char c); /*Ajouter à la fin de la chaîne de lettres la lettre de c. Pré -La chaîne de lettres a déjà été créée et sa longueur est < 80. Le caractère c est une lettre. Post -La lettre c a été ajoutée à la droite de la chaîne. La longueur de la chaîne est augmentée de 1.*/
Chapitre III - Introduction aux objets et aux classes31 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.h » (suite) bool Chaine_vide(); /*Indique si la chaîne de lettres est vide ou non. Pré -La chaîne de lettres a déjà été créée. Post -Si la chaîne de lettres renferme aucune lettre alors retourner true sinon retourner false.*/ bool Chaine_pleine(); /*Indique si la chaîne renferme 80 lettres ou -. Pré -La chaîne de lettres a déjà été créée. Post -Si la chaîne renferme 80 lettres alors retourner true sinon retourner false.*/
Chapitre III - Introduction aux objets et aux classes32 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.h » (fin) bool Lettre(char c); /*Indique si le caractère c est une lettre ou non. Pré -Nil. Post -Si c est une lettrealors retourner true sinon retourner false.*/ void Chaine_inversee(); /*Permet d'inverser une chaîne de lettres. Pré -La chaîne de lettres a déjà été créée. Post -La chaîne est obtenue en inversant la chaîne originale.*/ };
Chapitre III - Introduction aux objets et aux classes33 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.cpp » #include #include "Chaine_de_lettres.h" void Chaine_de_lettres::Creer_chaine_vide() { n = 0;chaine[0] = '\0'; } char Chaine_de_lettres::Extraire_lettre_la_plus_a_gauche() {assert(n > 0); int i;char c; n = n - 1;c = chaine[0]; for (i = 0; i <= n; i++) chaine[i] = chaine[i+1]; return c; }
Chapitre III - Introduction aux objets et aux classes34 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.cpp » (suite) void Chaine_de_lettres::Concatener_lettre_a_chaine(char c) {assert(n < 80); assert(Lettre(c)); chaine[n] = c; n = n + 1; chaine[n] = '\0'; } bool Chaine_de_lettres::Chaine_vide() { if (n > 0) return false; else return true; }
Chapitre III - Introduction aux objets et aux classes35 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.cpp » (suite) bool Chaine_de_lettres::Chaine_pleine() { if (n == 80)return true; elsereturn false; } bool Chaine_de_lettres::Lettre(char c) { if ((c>= 'A' && c <= 'Z') || (c>= 'a' && c <= 'z') || (c== ' '))return true; elsereturn false; }
Chapitre III - Introduction aux objets et aux classes36 Création de la classe « Chaine_de_lettres» Fichier « Chaine_de_lettres.cpp » (fin) void Chaine_de_lettres::Chaine_inversee() { int i; char c; for (i = 0; i < (n / 2); i++) { c = chaine[n - i - 1]; chaine[n - i - 1] = chaine[i]; chaine[i] = c; }
Chapitre III - Introduction aux objets et aux classes37 Création de la classe « Chaine_de_lettres» Fichier « Application Chaine_de_lettres.cpp » #include #include "Chaine_de_lettres.h" int main() { Chaine_de_lettres T;Chaine_de_lettres *pT; pT = new Chaine_de_lettres; T.Creer_chaine_vide(); T.Concatener_lettre_a_chaine('M'); T.Concatener_lettre_a_chaine('O'); T.Concatener_lettre_a_chaine('T'); T.Chaine_inversee();
Chapitre III - Introduction aux objets et aux classes38 Création de la classe « Chaine_de_lettres» Fichier « Application Chaine_de_lettres.cpp » (fin) cout << "1e :" << T.Extraire_lettre_la_plus_a_gauche(); if (T.Chaine_vide() == true ) cout << "Parfait."; pT -> Creer_chaine_vide(); pT -> Concatener_lettre_a_chaine('A'); cout Extraire_lettre_la_plus_a_gauche(); pT = &T; if (pT -> Chaine_vide() == true ) cout << "Parfait."; return 0; }
Chapitre III - Introduction aux objets et aux classes39 Création de la classe « Chaine_de_lettres» Chaine_de_lettres.h Chaine_de_lettres.cpp Application Chaine_de_lettres.cpp
Chapitre III - Introduction aux objets et aux classes40 Création de la classe « decision» class decision { /*Spécification fonctionnelle de la classe " décision " Domaine :L'ensemble des éléments de donnée est : {oui, non, peut_etre}.*/ private: enum choix { oui = 2, non = 0, peut_etre = 1} valeur_decision; public: void Affecter(int d); /*Opter pour la décision correspondante à d. Pré -d peut prendre les valeurs suivantes: 0, 1 ou 2. Post -La décision prise est celle correspondante à d.*/ Fichier « decision.h »
Chapitre III - Introduction aux objets et aux classes41 Création de la classe « decision» void Negation(); /*Changement de décision. Pré -La décision ne correspond pas à la valeur " peut-être " Post -La décision devient " oui " si elle était " non "; sinon, elle devient " non ".*/ int Conversion(); /*Convertit la décision en une valeur entière entre 0 et 2. Pré -Nil. Post -Si la décision vaut " oui ", " non " ou " peut-être " alors le résultat fourni est 2, 0 ou 1 respectivement.*/ }; Fichier « decision.h » (suite)
Chapitre III - Introduction aux objets et aux classes42 Création de la classe « decision» Fichier « decision.cpp » #include #include "Decision.h" void decision::Affecter(int d) {assert((d >= 0) && (d <= 2)); valeur_decision = (enum choix) d; } void decision::Negation() {assert(valeur_decision != peut_etre); if (valeur_decision == oui ) valeur_decision = non; else valeur_decision = oui; } int decision::Conversion() { return valeur_decision; }
Chapitre III - Introduction aux objets et aux classes43 Création de la classe « decision» Fichier « Application decision.cpp » #include #include "Decision.h" void main() { decision Reponse; decision *pReponse = &Reponse; Reponse.Affecter(2); cout << "Reponse I : " << Reponse.Conversion(); pReponse -> Affecter(0); cout Conversion(); pReponse -> Negation(); cout << "Reponse III : " << Reponse.Conversion(); }
Chapitre III - Introduction aux objets et aux classes44 Création de la classe « pile» pile.h pile.cpp Factorielle.cpp element_donnee_pile.h
Chapitre III - Introduction aux objets et aux classes45 Création de la classe « pile» typedef int element_donnee_pile; void copie_element_donnee_pile(element_donnee_pile *pe1, element_donnee_pile e2); /*Permet de copier e2 dans l'élément pointé par pe1. Pré -Nil Post -L'élément pointé par pe1 est initialisé à partir de e2. */ Fichier « element_donnee_pile.h »
Chapitre III - Introduction aux objets et aux classes46 Création de la classe « pile» Fichier « pile.h » #include "element_donnee_pile.h" class pile { /*Spécification fonctionnelle de la classe " pile ". Éléments :Le type de chaque élément de la pile peut être quelconque. Nous noterons par "element_donnee_pile" le type de chaque élément. Structure :Les éléments sont reliés entre eux permettant de déterminer l'ordre d'arrivée des éléments dans la pile. */
Chapitre III - Introduction aux objets et aux classes47 Création de la classe « pile» Fichier « pile.h » (suite) private: struct sommet_pile { element_donnee_pile element; struct sommet_pile *suivant; }; struct sommet_pile * pPile; public: void Creer_pile(); /*Permet de créer une pile vide. Pré -Nil. Post -La pile existe et est vide.*/
Chapitre III - Introduction aux objets et aux classes48 Création de la classe « pile» Fichier « pile.h » (suite) void Inserer(element_donnee_pile e); /*Insérer un élément e dans la pile. Pré -La pile a déjà été créée et n'est pas pleine. Post -La pile renferme e et l'interprète comme étant l'élément le plus récent inséré dans la pile.*/ void Enlever(element_donnee_pile *pe); /*Enlever un élément *pe de la pile. Pré -La pile a déjà été créée et n'est pas vide. Post -L'élément le plus récent inséré dans la pile est copié dans *pe; cet élément ne fait plus partie de la pile.*/
Chapitre III - Introduction aux objets et aux classes49 Création de la classe « pile» Fichier « pile.h » (suite) bool Pile_vide(); /*Vérifier si la pile est vide ou non. Pré -La pile a déjà été créée. Post -Si la pile ne possède aucun élément alors retourner true sinon retourner false.*/ bool Pile_pleine(); /*Vérifier si la pile est pleine ou non. Pré -La pile a déjà été créée. Post -Si la pile a atteint sa capacité maximale alors retourner vrai sinon retourner faux.*/
Chapitre III - Introduction aux objets et aux classes50 Création de la classe « pile» Fichier « pile.h » (fin) void Vider_pile(); /*Vider la pile. Pré -La pile a déjà été créée. Post -La pile est vide.*/ };
Chapitre III - Introduction aux objets et aux classes51 Création de la classe « pile» Fichier « pile.cpp » #include #include "Pile.h" void pile::Creer_pile() { pPile = NULL; } void pile::Inserer(element_donnee_pile e) {assert(Pile_pleine() != true); struct sommet_pile *pel = new sommet_pile; copie_element_donnee_pile(&((*pel).element), e); (*pel).suivant = pPile; pPile = pel; }
Chapitre III - Introduction aux objets et aux classes52 Création de la classe « pile» Fichier « pile.cpp » (suite) void pile::Enlever(element_donnee_pile *pe) { assert(Pile_vide() != true); struct sommet_pile *pel = NULL; copie_element_donnee_pile(pe, (*pPile).element); pel = pPile; pPile = (*pPile).suivant; delete(pel); } bool pile::Pile_vide() { if (pPile == NULL ) return true; else return false; }
Chapitre III - Introduction aux objets et aux classes53 Création de la classe « pile» Fichier « pile.cpp » (fin) bool pile::Pile_pleine() { /*Il n'y a aucune façon de tester si la liste chaînée est pleine i.e. s'il existe encore de l'espace disponible pour un autre sommet "sommet_pile".*/ return false; } void pile::Vider_pile() { element_donnee_pile el; element_donnee_pile *pel = ⪙ while (Pile_vide() == false) Enlever(pel); }
Chapitre III - Introduction aux objets et aux classes54 Création de la classe « pile» Fichier « Factorielle.cpp » #include #include "pile.h" int factorielle(int n); void main() { int n = 0; cout << "Entrez un nombre entier positif ou nul : "; cin >> n; cout << "La factorielle de " << n << " est : " << factorielle(n); }
Chapitre III - Introduction aux objets et aux classes55 Création de la classe « pile» Fichier « Factorielle.cpp » (suite) int factorielle(int N) { pile S;int i;int *pi = &i; int fact; int *pfact = &fact; if (N == 0) return 1; S.Creer_pile(); for(i = N; i >= 1; i = i - 1) S.Inserer(i); S.Enlever(pfact); while(S.Pile_vide() == false) {S.Enlever(pi); fact = i * fact; }; return fact; }
Chapitre III - Introduction aux objets et aux classes56 Création de la classe « pile» Fichier « Factorielle.cpp » (fin) void copie_element_donnee_pile(element_donnee_pile *pe1, element_donnee_pile e2) { *pe1 = e2; }
Chapitre III - Introduction aux objets et aux classes57 Création de la classe « Caisse_enregistreuse » Spécification fonctionnelle de la classe " Caisse_enregistreuse ". Dans le tiroir-caisse d'une caisse enregistreuse, nous avons une certaine somme en caisse constitué de billets de 50$, 20$, 10$ et de 5$ ainsi que de pièces de 2$, 1$, 50¢, 25¢, 10¢, 5¢ et de 1¢. Notre objectif est de simuler le comportement d'une caisse enregistreuse. Pour rendre le change exact à un client, la stratégie consiste à choisir à chaque étape le billet ou la pièce de valeur maximale laquelle est inférieure ou égale au montant qui reste à rendre au client. typedef enum Piece{deux_dollars = 0, un_dollar, cinquante_cents, vingt_cinq_cents, dix_cents, cinq_cents, un_cent}; typedef enum Billet{cinquante_dollars = 0, vingt_dollars, dix_dollars, cinq_dollars}; const int Valeur_des_billets[4] = {50, 20, 10, 5}; const int Valeur_des_pieces[7] = { 200, 100, 50, 25, 10, 5, 1}; const int Nombre_de_pieces_par_rouleau[7] = {25, 25, 40, 40, 50, 40, 50};
Chapitre III - Introduction aux objets et aux classes58 Création de la classe « Caisse_enregistreuse » class Caisse_enregistreuse { private: int Nb_de_billets_ou_de_pieces[11]; public: void Ouverture_d_une_caisse(); /*Création d'une caisse enregistreuse vide.*/ void Ouverture_d_une_caisse(int Billets[4], int Pieces[7]); /*Création d'une caisse enregistreuse où le nombre de billets de 50$, 20$, 10$ et 5$ ainsi que le nombre de pièces de 2$, 1$, 50¢, 25¢, 10¢, 5¢ et de 1¢ sont fixés grâce à ces deux paramètres. Pré -Chaque composante des deux vecteurs passés en paramètre est non négative.*/
Chapitre III - Introduction aux objets et aux classes59 Création de la classe « Caisse_enregistreuse » float Somme_en_caisse(); /*Retourne la somme en caisse dans la caisse enregistreuse. Pré -La caisse enregistreuse a été créée.*/ bool Existence_de_change(int dollars, int cents); /*Retourne TRUE si le tiroir-caisse possède les billets et les pièces nécessaires pour rendre le montant d'argent passé en paramètre. FALSE autrement. Pré -La caisse enregistreuse a été créée. dollars >= 0 et 0 <= cents < 100. */ void Ajouter_un_rouleau_au_tiroir_caisse(enum Piece P); /*Permet d'ajouter un rouleau au tiroir-caisse d'une certaine pièce. Pré -La caisse enregistreuse a été créée.*/
Chapitre III - Introduction aux objets et aux classes60 Création de la classe « Caisse_enregistreuse » void Transaction(int dollars, int cents, int Billets_remis_par_le_client[4], int Pieces_remises_par_le_client[7], int Billets_remis_au_client[4],int Pieces_remises_au_client[7]); /*Permet d'effectuer une transaction au montant de "dollars.cents" où les billets et les pièces remis par le client sont déposés dans le tiroir-caisse et le change est remis au client ce qui est soustrait du tiroir-caisse. Pré -La caisse enregistreuse a été créée. dollars ≥ 0 et 0 ≤ cents < 100. Chaque composante des 2 vecteurs passés en paramètre Billets_remis_par_le_client et Pieces_remises_par_le_client est non négative. Le montant remis par le client est supérieur ou égal au montant de la transaction. Le tiroir-caisse possède les billets et les pièces nécessaires pour rendre le change.*/
Chapitre III - Introduction aux objets et aux classes61 Création de la classe « Caisse_enregistreuse » int Nb_de_billets_en_caisse(enum Billet B); /*Retourne le nombre de billets dans le tiroir-caisse de Billet. Pré -La caisse enregistreuse a été créée.*/ int Nb_de_pieces_en_caisse(enum Piece P); /*Retourne le nombre de pièces dans le tiroir-caisse de Piece. Pré -La caisse enregistreuse a été créée.*/
Chapitre III - Introduction aux objets et aux classes62 Création de la classe « Caisse_enregistreuse » int Depot(int seuil_de_depot, int Nb_min_de_billets_en_caisse[4]); /*Permet de retirer une somme du tiroir-caisse pour dépôt seulement pour des raisons de sécurité si la somme en caisse incluant seulement les billets est supérieure ou égale à seuil_de_depot. Pré -La caisse enregistreuse a été créée. Le seuil de dépôt est supérieur ou égal à la somme qui résulte du nombre minimum de billets de 50$, de 20$, de 10$ et de 5$ que l'on retrouve dans le vecteur Nb_min_de_billets_en_caisse. On retrouve dans le tiroir-caisse au moins le nombre minimum de billets de 50$, de 20$, de 10$ et de 5$ que l'on retrouve dans le vecteur Nb_min_de_billets_en_caisse. La somme qui résulte du nombre minimum de billets de 50$, de 20$, de 10$ et de 5$ que l'on retrouve dans le vecteur Nb_min_de_billets_en_caisse est non nulle.
Chapitre III - Introduction aux objets et aux classes63 Création de la classe « Caisse_enregistreuse » Post -Retourne la somme retirée du tiroir-caisse. Si la somme en caisse incluant seulement les billets est ≤ seuil_de_depot, la somme retirée est nulle. Autrement, la somme retirée est la différence entre le montant en caisse et la somme qui résulte du nombre minimum de billets de 50$, de 20$, de 10$ et de 5$ que l'on retrouve dans le vecteur Nb_min_de_billets_en_caisse.*/ }; Voir l’implantation de cette classe et le programme d’application sur le site WEB.
Chapitre III - Introduction aux objets et aux classes64 Conclusion L’approche de la POO simplifie souvent les appels de fonctions, en réduisant le # de paramètres à passer. Cet avantage de la POO vient du fait que l’encapsulation des membres de données et des fonctions membres à l’intérieur d’un objet permettent aux fonctions membres d’accéder directement aux membres de données. L’utilisateur de l’objet de la classe n’est concerné que par les opérations encapsulées, incorporées, dans l’objet. De telles opérations sont conçues selon une orientation vers les clients plutôt qu’une orientation vers l’implantation. Les clients n’ont pas à se soucier de l’implantation réelle de la classe. Les changements dans l’implantation de la classe n’affectent pas les clients aussi longtemps que l’interface fournie aux clients demeure inchangée.
65 Conclusion L’identification comme private des membres de données et le contrôle d’accès à ces membres (surtout en écriture) par le biais des fonctions public aident à assurer l’intégrité des données. Les membres de fonctions ajustant les valeurs des données private doivent vérifier l’exactitude des nouvelles valeurs. Si elles ne sont pas exactes, ces fonctions doivent alors restituer aux données private un état cohérent approprié. À suivre … En plus de protéger les membres de données contre la réception de données non valables, l’accès à des données private par le biais de fonctions membres isole égale- ment les clients de la classe p/r à la représentation des membres de données. Par conséquent, si la représentation des données doit changer (pour réduire la mémoire requise ou améliorer la performance), seules les fonctions membres devront être changées et non les clients.