Introduction à la POO: Les classes vs les objets

Slides:



Advertisements
Présentations similaires
Sintaks : Tentative de guide de mise en œuvre Michel Hassenforder.
Advertisements

Erratum C Surcharge For(int x=0; … 2.
1 Quelques précisions sur l'héritage. 2 Signification de super.f() appel à la méthode f() masquée super : désigne l'objet appelant comme s'il était de.
Introduction à Java - les paquetages -
Programmation Orientée Objet (POO)
ESIEE Paris © Denis BUREAU I N Initiation à la programmation avec le langage Java.
Leçon 3 : Héritage IUP 2 Génie Informatique
FSAB1402: Informatique 2 Techniques de Programmation Orientée Objet
Programmation orientée objet
Principes de la technologie orientée objets
JavaBeans Réalise par: EL KHADRAOUY TARIK AOUTIL SAFOWAN.
Concepts de base : la Classe Pour faire une comparaison simple, une classe serait a priori, une structure C avec des variables et des fonctions.
Analyse et Conception orientée objet
Langage Oriente Objet Cours 4.
Principes de programmation (suite)
IFT1025, Programmation 2 Jian-Yun Nie
Introduction au paradigme objet Concepts importants surcharge (overload) redéfinition (override) Définition d’une classe Définition des attributs.
© 2007 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java et les Exceptions Peter Van Roy Département dIngénierie Informatique,
C++ : classes Introduction aux Langages Orientés Objets
77 Utilisation des classes (suite). 7-2 Objectifs A la fin de ce cours, vous serez capables de : Définir des méthodes surchargées dans une classe Fournir.
Quest-ce quune classe dallocation? Une classe dallocation détermine la portée et la durée de vie dun objet ou dune fonction.
Classes abstraites et Interfaces
Vers la conception objet
POO : Objets et classes (Rappels)
Langage Oriente Objet Cours 2.
Structures de données IFT-2000
Structures de données IFT-10541
66 Utilisation des classes et des objets. 6-2 Objectifs A la fin de ce cours, vous serez capables de : Créer de nouvelles classes à laide de Eclipse Utiliser.
GPA789 Analyse et conception orientées objet 1 Professeur: Tony Wong, Ph.D., ing. Chapitre 6 Correspondance UML et C++
Introduction au paradigme orienté-objet (suite)
P. Van Roy, LINF1251 LINF1251: Le Langage Java Peter Van Roy Département dIngénierie Informatique, UCL
Types de données abstrait et mécanismes d'encapsulation
Langages orientés objets
COURS DE PROGRAMMATION ORIENTEE OBJET :
Leçon 1 : notion dobjet IUP Génie Informatique Besançon Méthode et Outils pour la Programmation Françoise Greffier Université de Franche-Comté.
99 Réutilisation du code grâce à l'héritage. 9-2 Objectifs À la fin de ce cours, vous serez capables de : Définir l'héritage Utiliser l'héritage pour.
Structures de données IFT-2000 Abder Alikacem L’héritage en C++ Département d’informatique et de génie logiciel Édition Septembre 2009.
Classes et objets Types de données abstraits, programmation orientée objet, classes, objets,
Structures de données IFT-2000 Abder Alikacem Concepts orientés objet Édition Septembre 2009 Département dinformatique et de génie logiciel Département.
Travaux Pratiques Représentation des connaissances
Objectifs À la fin de ce cours, vous serez capables de :
La notion de type revisitée en POO
La Modélisation Orientée Objet Concevoir un programme : modélisation du problème à résoudre Notion de programme : machine de Turing Pouvoir d’expression.
Programmation objet La base.
Les modules. Modules Un module est un ensemble de définitions de constantes, de variables et de fonctions réutilisables de projet en projet. Le langage.
Master 1 SIGLIS Java Lecteur Stéphane Tallard Chapitre 1 – Objets et Classes Master 1 SIGLIS1Java Lecteur - Chapitre 1 Objets et classes.
© 2005 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java Peter Van Roy Département d’Ingénierie Informatique, UCL
Tutorat en bio-informatique
Introduction à la programmation objet en C++
5ième Classe (Mercredi, 19 octobre) Prog CSI2572.
C++ L’HERITAGE Fayçal BRAÏKI DUT INFORMATIQUE.
PHP objet Jérôme CUTRONA 10:13:27 Programmation Web
Les classes présenté par: RAHMOUNE RIME / ZEKRI SELMA.
Méthodes et outils de conception Introduction à la programmation Paramètre de retour Appel d’une fonction Portée des variables Définition Pourquoi les.
Chapitre III Introduction aux objets et aux classes.
Les classes Introduction aux Langages Orientés Objets
Conception de Programmes - IUT de Paris - 1ère année Conception de Programmes Objectifs et organisation du cours Introduction à la P.O.O.
Chapitre VII Techniques plus avancées à travers le concept de classe.
Chapitre 2 Rappels objet et Présentation des diagrammes UML
Chapitre 2 Rappels objet et Présentation des diagrammes UML
Campus-Booster ID : Copyright © SUPINFO. All rights reserved La programmation objet, un fondement de la programmation évènementielle.
Introduction à la Programmation Orientée Objet
Conception de Programmes - IUT de Paris - 1ère année Les classes Introduction Déclaration d’une classe Utilisation d’une classe Définition des.
JAVA et l'orientation objet Jean-Jacques LE COZ. Encapsulation L'encapsulation est le concept de masquer l'implémentation de la classe De ne permettre.
Introduction à la Programmation Orientée Objet H.GATI.
Transcription de la présentation:

Introduction à la POO: Les classes vs les objets Chapitre 1 Introduction à la POO: Les classes vs les objets 420-KAB-LG Programmation orientée par objets

Programmation procédurale ou orientée par objets? La programmation procédurale: La programmation orientée par objets: Tas de données Méthode 1 Méthode 4 Méthode 2 Méthode 5 Méthode 3 Méthode 6 Données Méthode 1 Méthode 3 Méthode 5 Méthode 2 Méthode 4 Méthode 6 420-KAB-LG Programmation orientée par objets

Avantages de la POO Pour le programmeur: De façon plus générale: Permet de rassembler des données qui vont logiquement ensemble afin de les traiter comme un tout. Protège les données en limitant le traitement à ce qui est prévu par l’objet uniquement. De façon plus générale: Elle augmente l’intelligibilité des programmes en rassemblant les données et les traitements qui s’appliquent à elles. Elle facilite la réutilisation de morceaux de programmes. Elle facilite la mise à jour et l’ajout de fonctionnalités. 420-KAB-LG Programmation orientée par objets

Un objet... Définition: « Chose solide ayant unité et indépendance. » Dans le contexte informatique un objet peut représenter: Un objet concret : une chaise, un bureau, une personne... Un objet abstrait: un compte de banque, un cours de programmation… Un objet se compare à une variable: il doit être déclaré avant d’être utilisé et a une durée de vie. 420-KAB-LG Programmation orientée par objets

Une classe... Définition: « Idée abstraite servant à modéliser un ensemble d’objets concrets. » Une classe se compare à un type. L’existence d’un type ne représente rien tant qu’on n’a pas déclaré une variable. La classe n’est qu’un moule servant à créer des objets. Un objet est aussi nommé une instance d’une classe. Une classe possède des membres: Attributs: variables qui représentent les données de l’objet. Les valeurs de ces données sont les états de l’objet. Chaque objet a un ensemble d’attributs (de variables) qui lui est propre. Méthodes: actions qui s’appliquent à l’objet ou encore services que peut rendre l’objet. On déclare des objets d’une classe tout comme on déclare des variables d’un certain type. La classe est une extension de la notion de structure... 420-KAB-LG Programmation orientée par objets

Attributs ou propriétés Définition: « Une caractéristique ou un état que possède tous les objets d’une même classe mais dont le contenu peut varier d’un objet à l’autre. » 420-KAB-LG Programmation orientée par objets

Méthodes Définition: « Une méthode est un sous-programme qui appartient à une classe et effectue un traitement sur les attributs de cette classe ». Une méthode peut servir à: Modifier la valeur d’un attribut (setter) Obtenir la valeur d’un attribut (getter) Effectuer un traitement plus général 420-KAB-LG Programmation orientée par objets

Les modificateurs d’accès public: Le membre est visible à l’intérieur de la classe comme de l’extérieur (interface). private: Le membre n’est visible qu’à l’intérieur de la classe (encapsulation). La seule différence entre une classe et une structure est l’accès par défaut (si non spécifié): Pour une classe: private Pour une structure: public (rétrocompatibilité) protected: Le membre n’est visible qu’à l’intérieur de la classe et ses dérivées (dans le contexte de l’héritage) 420-KAB-LG Programmation orientée par objets

Représentation UML d’une classe Accès: Privé + Publique # Protégé Nom Attributs Méthodes 420-KAB-LG Programmation orientée par objets

Conception d’une classe... Une classe a des méthodes et des attributs (on peut faire la distinction entre un attribut fixe (caractéristique) ou variable (état)) La classe se protège et assure sa cohérence interne! La classe fournie une interface simple (des méthodes publiques) mais complète! Un attribut est toujours privé! Accès à un attribut: Aucun Lecture seule (“getter”) Lecture et écriture (“getter” et “setter”) 420-KAB-LG Programmation orientée par objets

Trois grands principes de la POO 420-KAB-LG Programmation orientée par objets

1. L’encapsulation Définition: « Exposer les fonctionnalités d’un objet tout en cachant les structures de données et les détails d’implémentation. »   Indépendance: Afin d’assurer la cohérence interne d’un objet, seul ce dernier doit pouvoir lire et modifier ses attributs. Les attributs devraient donc toujours être privés! Les méthodes publiques implémentent l’interface d’utilisation. Elle doit être simple mais complète. Elle doit aussi assurer la cohérence. Unité: Il existe un lien cohérent entre les attributs. Les méthodes doivent lire et/ou modifier les attributs. 420-KAB-LG Programmation orientée par objets

2. L’héritage Permet la généralisation: c’est une caractéristique importante d’un langage naturel! Simplifie les programmes en évitant la redondance. 420-KAB-LG Programmation orientée par objets

3. Le polymorphisme Définition: « Le polymorphisme consiste à faire abstraction de la forme. » Méthode abstraite Prendre l’automobile Prendre l’autobus 420-KAB-LG Programmation orientée par objets

Un exemple en C++ class CBicyclette { public: void Freiner(); void Pedaler(); string ObtenirCouleur(); void ModifierCouleur(string couleur); private: string Couleur_; float Vitesse_; int Hauteur_; }; 420-KAB-LG Programmation orientée par objets

Écriture d’une classe Déclaration dans le .h: Utilisation: class CEntierEncapsule { int Entier_; public: void SetEntier(int NouvelEntier); int GetEntier() const; }; Définition dans le .cpp: void CEntierEncapsule::SetEntier(int NouvelEntier) Entier_ = NouvelEntier; } Utilisation: int main() { CEntierEncapsule UnObjet; UnObjet.SetEntier( 10 ); cout << UnObjet.GetEntier(); } 420-KAB-LG Programmation orientée par objets

Procédurale VS Objets bool EstAdulte(int Param) class CPersonne { { return Param>= 18; } int main() int Age; Age= 19; cout << EstAdulte(Age); class CPersonne { public: int Age; bool EstAdulte() return Age >=18; } }; int main() CPersonne Joan; Joan.Age = 19; cout << Joan.EstAdulte(); 420-KAB-LG Programmation orientée par objets

Les méthodes constantes Le mot-clé const après la déclaration d’une méthode garantit que cette méthode ne modifiera aucun des attributs de la classe. C’est une protection pour le programmeur. C’est une excellente pratique que de déclarer les accesseurs const (ainsi que toute autre méthode qui n’a pas besoin de modifier les attributs de l’objet). Exemple: int GetEntier() const; 420-KAB-LG Programmation orientée par objets

Ancienne façon de faire un cast Vers la POO: Avant float Quotient(int Num, int Den) { float q =0.0f; if(Den!=0) q = (float)Num / (float)Den; return q; } int main() int n=3; int d=4; cout << Quotient(3,4) << endl; Ancienne façon de faire un cast 420-KAB-LG Programmation orientée par objets

Apparition d’un nouveau concept et regroupement des données Vers la POO: Naissance struct Fraction { int Num; int Den; }; float Quotient(Fraction Fr) float q = 0.0f; if(Fr.Den!=0) q = static_cast<float>(Fr.Num) / static_cast<float>(Fr.Den) ; return q; } int main() Fraction Frac; Frac.Num = 3; Frac.Den = 4; cout << Quotient(Frac) << endl; Apparition d’un nouveau concept et regroupement des données 420-KAB-LG Programmation orientée par objets

Vers la POO: Intégration class Fraction { public: int Num; int Den; float Quotient() float q = 0.0f; if(Den!=0) q = static_cast<float>(Num) / static_cast<float>(Den); return q; } }; int main() Fraction Frac; Frac.Num = 3; Frac.Den = 4; cout << Frac.Quotient() << endl; Ajout de la méthode à la classe: Regroupement des données et des méthodes qui utilisent ces données 420-KAB-LG Programmation orientée par objets

Ce qu’il faut retenir... Il faut bien comprendre les structures (ref. KA0) pour apprendre la POO. À partir de maintenant nous ajouterons des fonctions à nos structures! Nous utiliserons le mot-clé class au lieu de struct mais il y a peu de différences pour le compilateur 420-KAB-LG Programmation orientée par objets

Chapitre 2 Le cycle de vie Construction Utilisation Destruction 420-KAB-LG Programmation orientée par objets

Les services par défaut d’une classe La construction Allocation de la mémoire Attributs non-initialisés La construction d’une copie Copie membre à membre (shallow copy) L’affectation entre objets d’une même classe La destruction Libération de la mémoire Les services par défaut peuvent être redéfinis! 420-KAB-LG Programmation orientée par objets

Exemple // Fichier EntierEncapsule.h class CEntierEncapsule { public: int GetEntier() const; void SetEntier(int Entier); private: int Entier_; }; 420-KAB-LG Programmation orientée par objets

Exemple (suite) int main() { CEntierEncapsule Entier1, // Construction par défaut Entier2; Entier1.SetEntier(10); AfficherObjet(Entier1); Entier2 = Entier1; // Affectation d’un objet à un autre AfficherObjet(Entier2); system("Pause"); } // Destruction des objets void AfficherObjet(CEntierEncapsule EntierEncapsule) // Construction d’une copie cout << EntierEncapsule.GetEntier() << endl; } // Destruction de l’objet // passé en paramètre 420-KAB-LG Programmation orientée par objets

Les services par défaut (suite) Parfois le service par défaut ne suffit pas! Par exemple, la construction par défaut n’initialise pas les attributs! Nous pouvons implémenter nous-mêmes la construction d’un objet, la copie, l’affectation et la destruction d’un objet. 420-KAB-LG Programmation orientée par objets

Les services par défaut (suite) La déclaration d’un constructeur permet d’initialiser l’objet après l’allocation de l’objet. La déclaration d’un constructeur de copie dans une classe remplace le constructeur de copie par défaut. La déclaration d’un destructeur dans une classe permet de faire le ménage avant la libération de l’objet. La surcharge de l’opérateur ‘=’ remplace le service par défaut d’affectation. 420-KAB-LG Programmation orientée par objets

Le constructeur Qu’affiche à l’écran le programme suivant? int main() { CEntierEncapsule UnObjet;   cout << UnObjet.GetEntier() << endl; } Une valeur aléatoire car la construction par défaut n’initialise pas les attributs! (comme au laboratoire!) 420-KAB-LG Programmation orientée par objets

Le constructeur (suite) Il faudrait plutôt faire: int main() { CEntierEncapsule UnObjet; UnObjet.SetEntier(20);   cout << UnObjet.GetEntier() << endl; } Cela ne devrait pas être la responsabilité de l’utilisateur de la classe d’initialiser l’objet, mais à l’objet lui-même de s’initialiser correctement! 420-KAB-LG Programmation orientée par objets

Le constructeur (suite) Lors de la construction d’un objet, le compilateur invoque automatiquement une méthode qui se charge de l’initialisation de l’objet. Cette méthode spéciale se nomme un constructeur. Doit initialiser tous les attributs et exécuter toutes autres instructions requises pour initialiser l’objet. N’a pas de valeur de retour (même pas void!) Porte le même nom que la classe. Peut avoir des paramètres ou non. On peut définir plusieurs constructeurs pour une même classe, mais ils doivent avoir des signatures différentes. 420-KAB-LG Programmation orientée par objets

Le constructeur sans paramètres Il est unique! Exemple: class CEntierEncapsule { public: CEntierEncapsule(); // Même nom que la classe // pas de type de retour! };   CEntierEncapsule::CEntierEncapsule() // Définition Entier_ = 0; // ou encore mieux SetEntier(0); } 420-KAB-LG Programmation orientée par objets

Le constructeur sans paramètre (suite) Et maintenant, qu’affiche à l’écran le programme suivant? int main() { CEntierEncapsule UnObjet;   cout << UnObjet.GetEntier() << endl; } Il affiche 0 ! N’est-ce pas génial?? Appel automatique du constructeur sans paramètre 420-KAB-LG Programmation orientée par objets

Les constructeurs avec paramètre(s) Exemple: class CEntierEncapsule { public: CEntierEncapsule(int Valeur); // Même nom que la classe // pas de type de retour! }; // un paramètre int   CEntierEncapsule::CEntierEncapsule(int Valeur) Entier_ = Valeur; //ou encore mieux SetEntier(Valeur); } 420-KAB-LG Programmation orientée par objets

Les constructeurs avec paramètres (suite) Appel automatique du constructeur qui prend un int int main() { CEntierEncapsule UnObjet(99);   cout << UnObjet.GetEntier() << endl; } Il affiche 99 ! 420-KAB-LG Programmation orientée par objets

La valeur par défaut d’un paramètre En C++, un paramètre peut avoir une valeur par défaut. La valeur est définie dans le prototype seulement (.h). Si le paramètre n’est pas spécifié lors de l’appel, la valeur par défaut est utilisée. Exemple: void Afficher(string Message="Bonjour", int Fois = 1); Peut être appelé de trois façons: Afficher("Salut", 5); // Affiche Salut 5 fois Afficher("Allo"); // Affiche Allo 1 fois Afficher(); // Affiche Bonjour 1 fois Par contre, Afficher(5) donne une erreur de compilation… 420-KAB-LG Programmation orientée par objets

La valeur par défaut et les constructeurs On peut donc remplacer plusieurs constructeurs par un seul constructeur avec des paramètres avec des valeurs par défaut! Évite la redondance du code. Exemple: class CPersonne { public: CPersonne(string Nom="Roger", int Age=20); // remplace avantageusement: // CPersonne(); // CPersonne(string Nom); // CPersonne(string Nom, int Age); };   420-KAB-LG Programmation orientée par objets

Le constructeur de copie Appelé de façon implicite lorsque: Un objet est passé en tant que paramètre par valeur Un objet est retourné par une fonction Un objet est construit à partir d’un autre objet Son rôle est de créer une copie exacte de l’objet passé en paramètre Sa signature est toujours la même: NomClasse (const NomClasse& Original); 420-KAB-LG Programmation orientée par objets

Le constructeur de copie class CEntierEncapsule { public: CEntierEncapsule(const CEntierEncapsule& Original); }; CEntierEncapsule::CEntierEncapsule(const CEntierEncapsule& Original) Entier_ = Original.GetEntier(); // ou encore mieux: SetEntier(Original.GetEntier() ); } Pourquoi un passage par référence?? 420-KAB-LG Programmation orientée par objets

Si le constructeur de copie utilisait un passage par valeur… int main() { A a; A b(a); } class A public: A(const A p); }; Appel de b.CtrCopie(a) Appel de p.CtrCopie(a) Appel de p.CtrCopie(a) Appel de p.CtrCopie(a) 420-KAB-LG Programmation orientée par objets Appel de p.CtrCopie(a)

Les paramètres constants Un paramètre déclaré const indique qu’il ne pourra pas être modifié à l’intérieur de la méthode. On peut aussi déclarer un objet local constant. Sur les objets et les paramètres const, on ne peut appeler que des méthodes const, pour respecter la garantie! Exemple: CEntierEncapsule::CEntierEncapsule(const CEntierEncapsule& Original) 420-KAB-LG Programmation orientée par objets

Le const est un virus… const class CRect { int x_,y_; public: CRect(const CRect& Autre); void GetX() ; void GetY() ; }; CRect::CRect(const CRect& Autre) x_ = Autre.GetX(); } Erreur: impossible de convertir un pointeur 'this' de 'const CRect&' en ‘CRect&' 420-KAB-LG Programmation orientée par objets const

Le destructeur N’a pas de valeur de retour A le même nom que la classe préfixé du symbole ~ Effectue les instructions appropriées lorsque l’objet est détruit Fermeture d’un fichier Destruction de mémoire allouée dynamiquement Pour l’instant, le service par défaut fera l’affaire! 420-KAB-LG Programmation orientée par objets

Le destructeur (suite) class CEntierEncapsule { public: ~CEntierEncapsule(); }; CEntierEncapsule::~CEntierEncapsule() cout << "Rien à faire pour l’instant…" << endl; } int main() CEntierEncapsule UnObjet(99); cout << UnObjet.GetEntier() << endl; Appel automatique du destructeur! 420-KAB-LG Programmation orientée par objets

Les caprices des constructeurs Dès qu’au moins un constructeur est défini, le service de construction par défaut disparait! Un constructeur sans paramètre est souvent essentiel (tableaux, composition, héritage, etc.) Attention de ne pas créer des situations ambiguës: class CPasClair { CPasClair(); CPasClair(int i=3); }; int main() CPasClair a; // error C2668: 'CPasClair::CPasClair' : // appel ambigu à une fonction surchargée } 420-KAB-LG Programmation orientée par objets

Chapitre 3 Les relations 420-KAB-LG Programmation orientée par objets

Diagramme de classes UML 420-KAB-LG Programmation orientée par objets

Relations entre les classes Il existe plusieurs types de relations entre deux classes: Aucune relation Classes complètement indépendantes Utilisation Simple dépendance: paramètre, variable locale ou valeur de retour 420-KAB-LG Programmation orientée par objets

Relations entre les classes (suite) Composition Agrégation Héritage 420-KAB-LG Programmation orientée par objets

La relation crée une dépendance La classe A qui a une relation avec la classe B devient dépendante de cette dernière Une classe dépendante d’une autre classe fait des #include « B.h » La modification d’une classe provoque normalement la recompilation des classes dépendantes (erreurs?) Peut amener un mauvais fonctionnement des classes dépendantes 420-KAB-LG Programmation orientée par objets

L’utilisation Première relation: 420-KAB-LG Programmation orientée par objets

L’utilisation Une classe peut utiliser une autre classe de trois façons: En paramètre d’une méthode En variable locale dans une méthode En valeur de retour d’une méthode 420-KAB-LG Programmation orientée par objets

…en paramètre type A::Methode(B b) type A::Methode(B& b) type A::Methode(const B& b) Exemples: bool CBanque::Bloquer(Compte c); void CConsole:: Afficher(const string& Message); void CFenetre::Afficher (CImage& Image, int x, int y); 420-KAB-LG Programmation orientée par objets

… en variable locale type A::Methode() { B b; } bool CResto::Payer(float Montant) CFacture Facture(Montant); Facture.Imprimer(); //… 420-KAB-LG Programmation orientée par objets

… en valeur de retour B A::Methode() { B b; return b; } Exemple: // … return b; } Exemple: COeuf CPoule::Pondre() COeuf UnOeuf; return UnOeuf; 420-KAB-LG Programmation orientée par objets

Deuxième relation: La composition 420-KAB-LG Programmation orientée par objets

Mise en contexte (CAuto) class CAuto { public: CAuto(); ~CAuto(); int GetNbChevaux() const; void SetNbChevaux(int NbChevaux); void DegonflerUneRoue(int i); private: int NbChevauxDuMoteur_; int PressionDesRoues_[4]; }; 420-KAB-LG Programmation orientée par objets

Classes CRoue et CMoteur -Pression_:int +Dégonfler() CMoteur -NbChevaux_:int +GetNbChevaux():int +SetNbChevaux(entrée NbChevaux:int) 420-KAB-LG Programmation orientée par objets

Classe CAuto améliorée class CAuto { public: CAuto(); ~CAuto(); CRoue& GetRoue(int Index); void Modifier(int NbChevaux); private: CMoteur& GetMoteur(); CMoteur SuperMoteur_; CRoue Roues_[4]; }; 420-KAB-LG Programmation orientée par objets

La composition La composition est un type de relation entre deux classes qui implique une notion de contenance. On dit que A et B sont deux classes reliées par une relation de composition, c’est-à-dire que A est composée de B A = Composée ; B= Composant 420-KAB-LG Programmation orientée par objets

La composition Exemples: Un objet Auto se compose d’objets moteur et roues. Un objet Hôtel se compose d’objets ChambreHôtel Un objet Ordinateur se compose d’objets CPU, clavier et écran Un objet mammifère se compose d’objets tête, 4 pattes 420-KAB-LG Programmation orientée par objets 61

La composition Le composant est utilisé comme attribut du composé. Les cycles de vie du composé et ses composants sont intimement liés. Il s’agit d’une agréagation forte: si le composé est détruit, ses composants disparaissent aussi 420-KAB-LG Programmation orientée par objets 62

Construction / destruction d’une composition Si un objet B est un attribut de l’objet A, le constructeur de l’objet B sera appelé avant celui de l’objet A. Ceci est logique: pour construire une auto, il faut d’abord construire ses composantes, comme le moteur et les roues. Raison: Accès possible 420-KAB-LG Programmation orientée par objets

Construction / destruction d’une composition Lors de la destruction c’est l’inverse Si on veut utiliser un autre constructeur que le constructeur par défaut (ou mixte), on peut sélectionner le constructeur à utiliser lors de la pré-construction 420-KAB-LG Programmation orientée par objets 64

La pré-construction CAuto::CAuto() : SuperMoteur_(90) { cout << "Constructeur de CAuto" << endl; } On peut même utiliser cette syntaxe pour initialiser tous les attributs : CChat::CChat(int Age, string Nom) : Age_(Age), Nom_(Nom) { } 420-KAB-LG Programmation orientée par objets

Agrégation forte vs faible Agrégation forte = Composition Agrégation faible : Le composant ne disparaît pas si le composé est détruit. Exemples: (Aéroport et avions), (Train et wagons), (groupe et étudiants), (Ferme et animaux) 420-KAB-LG Programmation orientée par objets

Représentation UML de la composition 420-KAB-LG Programmation orientée par objets

L’encapsulation appliquée à la composition class CAuto { public: CAuto(); ~CAuto(); const CRoue& GetRoue(int Index); void Modifier(int NbChevaux); private: CMoteur& GetMoteur(); CMoteur SuperMoteur_; CRoue Roues_[NBROUES]; }; L’accès à une roue est en lecture seule Pas d’accès direct au moteur 420-KAB-LG Programmation orientée par objets

Exécution du programme Auto 420-KAB-LG Programmation orientée par objets

L’héritage (2e grand principe de la POO) Troisième relation: L’héritage (2e grand principe de la POO) 420-KAB-LG Programmation orientée par objets

Motivation 420-KAB-LG Programmation orientée par objets

Généralisation Dérive de... Hérite de... Est une... Is a… Classe de base, parent ou générale Classes dérivées, enfants ou spécialisées Dérive de... Hérite de... Est une... Is a… 420-KAB-LG Programmation orientée par objets

L’Héritage L’héritage offre la possibilité de créer une classe à partir d’une autre. La nouvelle classe bénéficie des attributs et des méthodes de la classe dont elle dérive. On dira alors que la classe enfant hérite du parent ou que la classe dérivée hérite de la classe de base. Dans la classe dérivée, on peut définir de nouveaux membres afin de modifier et de spécialiser la classe de base.   420-KAB-LG Programmation orientée par objets

Déclaration de CPersonne class CPersonne { int Age_; public: CPersonne(int Age); ~CPersonne(); int GetAge() const; void SeDéplacer(); }; Classe normale, rien ne change! 420-KAB-LG Programmation orientée par objets

Déclaration de CEtudiant class CEtudiant : public CPersonne { int Note_; public: CEtudiant(int Age, int Note); ~CEtudiant(); int GetNote() const; void Etudier(); }; Indique que la classe dérive de CPersonne 420-KAB-LG Programmation orientée par objets

Déclaration de Enseignant class CEnseignant : public CPersonne { int Salaire_; public: CEnseignant(int Age, int Salaire); ~CEnseignant(); int GetSalaire() const; void Enseigner(); }; Indique que la classe dérive de CPersonne 420-KAB-LG Programmation orientée par objets

Exemple d’utilisation int main() { CEtudiant Paul(19, 85); Paul.Etudier(); cout << Paul.GetNote(); Paul.SetDéplacer(); cout << Paul.GetAge(); CEnseignant Joan(35, 15000); Joan.Enseigner(); cout << Joan.GetSalaire(); Joan.SeDéplacer(); cout << Joan.GetAge(); } Méthodes héritées de la classe parent Méthodes héritées de la classe parent 420-KAB-LG Programmation orientée par objets

Les modificateurs d’accès Les membres publics d’une classe sont utilisables par toutes les fonctions. Les membres privés d’une classe sont utilisables uniquement par les fonctions membres de cette classe. Les membres protégés d’une classe sont utilisables par les fonctions membres de cette classe ou d’une classe dérivée. 420-KAB-LG Programmation orientée par objets

420-KAB-LG Programmation orientée par objets

Construction et destruction Lors de la création d’un objet de la classe Etudiant, il y a deux constructeurs impliqués. Lorsqu’un objet Etudiant est détruit, il y a deux destructeurs qui participent à la destruction de l’objet. Quel est l’ordre d’appel des constructeurs et des destructeurs? Comment faire pour déterminer cet ordre? Pourquoi cet ordre précis? 420-KAB-LG Programmation orientée par objets

La pré-construction Lors de la pré-construction, on peut sélectionner le constructeur de la classe de base à utiliser pour acheminer de l’information à la classe de base: CEtudiant::CEtudiant(int Age, int Note): CPersonne(Age) { SetNote(Note); } La pré-construction peut aussi servir à sélectionner les constructeurs à utiliser lors de la construction d’un composé. 420-KAB-LG Programmation orientée par objets

Chapitre 4 Pointeurs, allocation dynamique et références 420-KAB-LG Programmation orientée par objets 82 82

Programmation orientée par objets Les pointeurs 0x20 0x24 5 0x20 420-KAB-LG Programmation orientée par objets 83 83

La variable a peut être de type primitif (int, char, …) ou un objet Les adresses On accède à l’adresse d’une variable (sa position en mémoire) avec le symbole & On accède au contenu d’une adresse avec le symbole * int main() { int a = 3; cout << a; // Affiche 3 cout << &a; // Affiche 0068FDF4 cout << *(&a); // Affiche 3, *(&a) = a } La variable a peut être de type primitif (int, char, …) ou un objet 420-KAB-LG Programmation orientée par objets

Les pointeurs Un pointeur contient et permet de manipuler l’adresse d’une variable ou d’un objet. Déclaration d’un pointeur: int *p; // Pointeur vers un int CEntier *pEntier; // Pointeur vers un CEntier short a, *b; // a est un short, b est // pointeur vers un short 420-KAB-LG Programmation orientée par objets

Exemple d’utilisation d’un pointeur (1) short a, *b; *a = 5; // invalide: a n’est pas un pointeur b = &a; // valide: b est un pointeur de // short, et &a est l'adresse d'un // short *b = 5; // valide: b est un pointeur de // short. Cette opération a pour // effet de déposer la valeur 5 // là où pointe b... donc dans a 420-KAB-LG Programmation orientée par objets

Exemple d’utilisation d’un pointeur (2) int main () { int a, // valeur de a: indéterminée b= 3; // valeur de b: 3 int *p; // p est un pointeur vers un int p= &a; // p  l’adresse de a; p pointe // vers a *p= 4; // le contenu pointé par p ( donc // a ) reçoit 4 b+= a; // b devient égal à 7! } 420-KAB-LG Programmation orientée par objets

Visualiser les pointeurs int a, b= 3; int *p; p= &a; *p= 4; 420-KAB-LG Programmation orientée par objets

Initialiser un pointeur En C, on utilisait la constante NULL, en C++ on utilise l’adresse 0 (zéro) int *p = 0; // (…) if (p != 0) { // ... p mène à un endroit valide } else // ... utiliser *p serait imprudent! ... 420-KAB-LG Programmation orientée par objets

Pointeurs et POO CEntier UnEntier(4) // Affiche 4 cout << UnEntier.GetEntier(); // Affiche 0072AB00 cout << &UnEntier; cout << (*(&UnEntier)).GetEntier(); 420-KAB-LG Programmation orientée par objets

Pointeurs et POO (suite) // Déclaration d’un pointeur vers un // objet CEntier *pEntier = 0; // Allocation dynamique d’un objet pEntier = new CEntier(3); // Appel des méthodes de l’objet pointé // par pEntier (*pEntier).SetEntier(3); cout << (*pEntier).GetEntier() << endl; 420-KAB-LG Programmation orientée par objets

L’opérateur -> L’opérateur -> est une syntaxe abrégée qui permet de sélectionner un membre d’un objet pointé par un pointeur: (*pEntier).SetEntier(3); est identique à pEntier->SetEntier(3); 420-KAB-LG Programmation orientée par objets

Passer un pointeur en paramètre void Afficher(CEntier* pEntier) { cout << pEntier->GetEntier(); } int main() CEntier Entier(3); CEntier *pEntier = new CEntier(4); Afficher(&Entier); Afficher(pEntier); 420-KAB-LG Programmation orientée par objets

Passer un pointeur en paramètre (suite) Très similaire au passage par référence Il n’y a pas de copie d’objets effectués Les modifications apportées à l’objet dans la méthode ou la fonction se répercuteront à l’extérieur de la méthode ou de la fonction. Cependant, contrairement à la référence, un pointeur peut être nul ou invalide. 420-KAB-LG Programmation orientée par objets

Retourner un pointeur CEntier* Creer(int iValeur) { return new CEntier(iValeur); } int main() CEntier *pEntier = Creer(5); cout << pEntier->GetEntier(); 420-KAB-LG Programmation orientée par objets

Erreur à ne jamais faire! (1) CEntier* Creer(int Valeur) { CEntier EntierLocal(Valeur); return &EntierLocal; } int main() CEntier *pEntier = Creer(5); cout << pEntier->GetEntier(); 420-KAB-LG Programmation orientée par objets

Détruire un objet créé dynamiquement int main() { CEntier *pEntier = new CEntier(6); cout << pEntier->GetEntier(); // … delete pEntier; } Il est de bon usage que celui qui créé un objet soit responsable de le détruire. 420-KAB-LG Programmation orientée par objets

Erreur à ne jamais faire! (2) CEntier Entier(3); CEntier *pEntier = 0; CEntier *pEntier2 = 0; pEntier = &Entier; pEntier2 = pEntier; delete pEntier; delete pEntier2; 420-KAB-LG Programmation orientée par objets

Pile vs Tas Tas 0xBB 0xBB (p) CEtudiant Pile 2 (j) 0 (p) 2 (i) int main() { int i = 2; CEtudiant *p = 0; p = new CEtudiant(); test(i); delete p; } void test(int j) cout << j; CEtudiant Pile 2 (j) 0 (p) 2 (i) 420-KAB-LG Programmation orientée par objets

L’allocation dynamique (et application du cycle de vie) 420-KAB-LG Programmation orientée par objets 420-KAB-LG Programmation orientée par objets 100 100

Le tableau automatique (rappel) La taille du tableau doit être connue à la compilation: int TabEntiers [ 100 ]; Encore mieux: const int NbCases = 15; int TabValeurs [ NbCases ]; 420-KAB-LG Programmation orientée par objets

Exemples qui ne compilent pas int NbCases = 15; int TabValeurs [ NbCases ]; Exemple 2: int NbCases; cin >> NbCases; Exemple 3: void CreerTableau(int Taille) { const int TAILLE = Taille; int Tableau[TAILLE]; } 420-KAB-LG Programmation orientée par objets

Le tableau dynamique Un tableau dynamique peut avoir une taille différente à chaque exécution L’espace mémoire est réservé à l’exécution et non à la compilation comme un tableau automatique Le tableau est alloué sur le tas et non sur la pile L’utilisation d’un tableau dynamique se fait en 5 étapes: Déclaration d’un pointeur pour contenir l’adresse mémoire (le point de départ) du tableau Réservation de l’espace mémoire avec l’opérateur new [] Conserver la taille du tableau dans une variable Utiliser le tableau comme s’il était un tableau automatique Lorsque le tableau n’est plus requis, libérer l'espace en mémoire avec l’opérateur delete [ ] 420-KAB-LG Programmation orientée par objets

Exemple int NbCases; // Taille du tableau int *TabEntiers; // Pointeur pour retenir l’adresse // du tableau dynamique. cin >> NbCases; // Demander la taille à l’usager // Allocation de la mémoire et affectation de l’adresse TabEntiers = new int [NbCases]; // Utilisation du tableau for (int i = 0; i < NbCases; i++) { TabEntiers[i] = i * i; cout << TabEntiers[i] << endl; } // Destruction de la mémoire allouée. delete [] TabEntiers; 420-KAB-LG Programmation orientée par objets

Automatique vs dynamique int main() { const int Nb=10; int Tab[Nb]; // utilisation … } int main() { int Nb=10; int *Tab = new int[Nb]; // utilisation … delete [] Tab; } 420-KAB-LG Programmation orientée par objets

La fuite mémoire Défaut de programmation grave et difficile à trouver! Outils de vérification de code (BoundsChecker) Exemple: void Test() { int* Tab = new int[10]; // … } for(int i=0;i<1000000000;i++) char *c = new char[10]; Le delete [] a été oublié! Ne pas essayer à la maison… 420-KAB-LG Programmation orientée par objets

Encapsulation d’un tableau d’entiers (version allégée) CTabEntiers::CTabEntiers(int Taille) { Table_ = new int[Taille]; Taille_ = Taille; } CTabEntiers::~CTabEntiers() { delete [] Table_; void CTabEntiers::SetElement(int Index, int Entier) { Table_[Index] = Entier; int CTabEntiers::GetElement(int Index) const return Table_[Index]; 420-KAB-LG Programmation orientée par objets

Encapsulation d’un tableau d’entiers (suite) Que se passes-t-il lorsqu’on passe un objet de la classe CTabEntiers en paramètre par valeur? int main() { CTabEntiers Tab(3); Test(Tab); } Que se passe-t-il lorsqu’on construit un objet de la classe CTabEntiers à partir d’un autre? CTabEntiers Tab1(20); CTabEntiers Tab2(Tab1); void Test(CTabEntiers Param) { // … } Boum! Re-Boum! 420-KAB-LG Programmation orientée par objets

Encapsulation d’un tableau d’entiers (suite) Il faut donc absolument définir le constructeur de copies et l’opérateur d’affectation de la classe CTabEntiers: public: CTabEntiers(const CTabEntiers& Original); CTabEntiers& operator=(const CTabEntiers& Original); La trinité Constructeur de copie Opérateur d’affectation Destructeur 420-KAB-LG Programmation orientée par objets

Encapsulation d’un tableau d’entiers Afin de compléter les fonctionnalités de la classe CTabEntiers, pouvez-vous écrire une méthode qui permettra de modifier la taille du tableau? public: void ModifierTaille(int NouvelleTaille, bool ConserverValeurs); 420-KAB-LG Programmation orientée par objets

Les tableaux d’objets Les tableaux automatiques De types primitifs int Notes[10]; char Chaine[10]; De type utilisateurs De structures SCompte MesComptes[10]; SPoint Flocons[10]; De classes CTasse MesTasses[10]; CMenu MesMenus[10]; De pointeurs! C’est toujours la même syntaxe: Type Nom[TAILLE] 420-KAB-LG Programmation orientée par objets

Les tableaux d’objets (suite) Les tableaux dynamiques De types primitifs int *Tab = new int [10]; … delete [] Tab; De type utilisateurs De structures SPoint *Flocons = new SPoint [10]; … delete [] Flocons; De classes CTasse *Tasses = new CTasse [10]; … delete [] Tasses; De pointeurs! C’est toujours la même syntaxe: Type *Nom = new Type[TAILLE]; … delete [] Nom; 420-KAB-LG Programmation orientée par objets

Les tableaux d’objets (suite) Lorsqu’on déclare un tableau d’objets: CMenu *MesMenus = new CMenu [10]; Ou CMenu MesMenus[10]; Il y a appel du constructeur par défaut pour chaque élément du tableau Si aucun constructeur n’est défini: utilisation du constructeur automatique Si un constructeur est défini, mais pas le constructeur par défaut: erreur de compilation! (le constructeur de copie échappe à cette règle) 420-KAB-LG Programmation orientée par objets

Exemple 1 - Un objet int main() { CSou Sou; Sou.Deplacer(); } 420-KAB-LG Programmation orientée par objets

Exemple 2 - Un tableau automatique d’objets int main() { const int Nb = 5; CSou Sou[Nb]; for(int i=0;i<NB;i++) Sou[i].Deplacer(); } 420-KAB-LG Programmation orientée par objets

Exemple 3 - Un tableau dynamique d’objets int main() { int Nb = 5; CSou* pSou = new CSou[Nb]; for(int i=0;i<Nb;i++) pSou[i].Deplacer(); } delete[] pSou; 420-KAB-LG Programmation orientée par objets

Exemple 4 - Un pointeur d’objet int main() { CSou* pSou = new CSou(); pSou->Deplacer(); delete pSou; } 420-KAB-LG Programmation orientée par objets

Exemple 5 - Un tableau automatique de pointeurs d’objets (ex 4.8) int main() { const int Nb = 5; CSou* pSou[Nb]; for(int i=0;i<Nb;i++) pSou[i] = new CSou; pSou[i]->Deplacer(); delete pSou[i]; } 420-KAB-LG Programmation orientée par objets

Exemple 6 - Un tableau dynamique de pointeurs d’objets int main() { int Nb = 5; CSou** pSou; pSou = new Csou*[5]; for(int i=0;i<Nb;i++) pSou[i] = new CSou; pSou[i]->Deplacer(); delete pSou[i]; delete[] pSou; } 420-KAB-LG Programmation orientée par objets

& Les références 420-KAB-LG Programmation orientée par objets 120 120

Les références Tout comme le pointeur, la référence représente l’adresse d’un objet Contrairement au pointeur, la référence ne référera qu’à une seule et même chose tout au long de son existence, et devra conséquemment référer à quelque chose dès sa déclaration. On déclare une référence en préfixant son nom d’un “&”. Une référence peut être considérée comme étant au même endroit, en mémoire, que ce à quoi elle réfère. C’est un synonyme, un alias. 420-KAB-LG Programmation orientée par objets

Les références (exemple) int main () { int i = 5; // i est un int de valeur 5 int *p = 0; // p pointe « nulle part » ! int &r = i; // r est une réference à i i++; // i devient 6, r aussi (car r // réfère à i) r++; // i devient 7, r aussi p = &i; // p pointe vers i (*p)++; // i, r et *p deviennent 8 p = &r; // p pointe là où r réfère (p // pointe vers i) } 420-KAB-LG Programmation orientée par objets

Paramètre et retour par référence d’un objet CEntier ParValeur(CEntier Param) { Param.SetEntier(3); return Param; } CEntier& ParReference(CEntier& Param) 420-KAB-LG Programmation orientée par objets

Paramètre et retour par référence d’un objet (suite) CEntier Entier(1); for(int i=0;i<1000;++i) { // 2000 copies d’objets effectuées // 1000 affectations Entier = ParValeur(Entier); } // 0 copie d’objet effectuée Entier = ParReference(Entier); 420-KAB-LG Programmation orientée par objets

Répercutions des modifications void ParValeur(CEntier Param) { Param.SetEntier(3); } void ParReference(CEntier& Param) int main () CEntier Entier(1); ParValeur(Entier); cout << Entier.GetEntier(); // Ceci affiche 1 ParReference (Entier); cout << Entier.GetEntier(); // Ceci affiche 3 420-KAB-LG Programmation orientée par objets

Les références constantes int i = 5; // i est un int de valeur 5 const int *p = 0; // p pointe « nulle part »! const int &r = i; // r est une référence à i i++; // i devient 6, r aussi // (car r réfère à i) r++; // INTERDIT!!! p = &i; // p pointe vers i (*p)++; // INTERDIT!!! p = &r; // p pointe là où r réfère // (p pointe vers i) 420-KAB-LG Programmation orientée par objets

Les références constantes et les objets Il est souvent préférable d’utiliser une référence constante plutôt que de faire un passage par copie. Une référence constante sur un objet interdit d’appeler une de ses méthodes qui n’est pas constante car seules les méthodes constantes garantissent que l’objet ne sera pas modifié. void ReferenceConstante(const CEntier& Param) { // INTERDIT si CEntier::SetEntier(int) // n’est pas const! Param.SetEntier(3); } 420-KAB-LG Programmation orientée par objets

Retour par référence constante class CTableau { CEntier Tableau_[10]; public : // Le const permet de ne pas briser l’encapsulation! const CEntier& GetElement(int Index); void SetElement(int Index, int Entier); }; int main () CTableau Tab; // INTERDIT car CEntier::SetEntier(int) // n’est pas const Tab.GetElement(0).SetEntier(3); Tab.SetElement(0,3); // Ok! } 420-KAB-LG Programmation orientée par objets

Chapitre 5 - Le polymorphisme 3e grand principe de la POO « Qui peut prendre plusieurs formes » 420-KAB-LG Programmation orientée par objets 420-KAB-LG Programmation orientée par objets 129 129

La redéfinition de méthodes Redéfinition (override) != Surcharge (overload) 420-KAB-LG Programmation orientée par objets

La redéfinition de méthodes (suite) Méthodes avec la même signature, mais une définition différente: void CPersonne::SeDéplacer() { cout << "Marcher";} void CEtudiant::SeDéplacer() { cout << "Prendre son vélo";} void CEnseignant::SeDéplacer() { cout << "Prendre sa bmw" ; } 420-KAB-LG Programmation orientée par objets

La redéfinition de méthodes (suite) Les classes dérivées ont donc deux versions de la méthode SeDéplacer. Déterminez la version de la méthode utilisée dans les situations suivantes: CPersonne John; CEtudiant Bobby; CEnseignant Joan; John.SeDéplacer(): Bobby.SeDéplacer(); Joan.SeDéplacer(); 420-KAB-LG Programmation orientée par objets

Les pointeurs d’objets Si on déclare un pointeur vers un int, ce pointeur doit pointer vers un int. Si on fait pointer le pointeur de int vers un char, on obtient une erreur de compilation : int* p = new char; main.cpp(86) : error C2440: 'initialisation' : impossible de convertir de 'char *' en 'int *' Pour atteindre le polymorphisme, cette règle doit être assouplie pour les objets: Si on déclare un pointeur vers un objet de la classe A, ce pointeur doit pointer vers un objet de la classe A ou un objet d’une classe dérivée de A. 420-KAB-LG Programmation orientée par objets

Les pointeurs d’objets (suite) Pouvez-vous déterminer les lignes qui provoquent une erreur de compilation? Cpersonne *Obj1 = new CPersonne; CPersonne *Obj2 = new CEtudiant; CPersonne *Obj3 = new CEnseignant; CEtudiant *Obj4 = new CPersonne; CEtudiant *Obj5 = new CEtudiant; CEtudiant *Obj6 = new CEnseignant; CEnseignant *Obj7 = new CPersonne; CEnseignant *Obj8 = new CEtudiant; CEnseignant *Obj9 = new CEnseignant; Il y a donc maintenant une différence entre le type de pointeur utilisé et le type réel de l’objet!! 420-KAB-LG Programmation orientée par objets

Redéfinition de méthodes et pointeurs d’objets Par défaut, la version de la méthode utilisée est déterminée par le type de pointeur utilisé. Déterminez la version de la méthode utilisée dans les exemples suivants: Cpersonne *Obj1 = new CPersonne; CPersonne *Obj2 = new CEtudiant; CPersonne *Obj3 = new CEnseignant; CEtudiant *Obj5 = new CEtudiant; CEnseignant *Obj9 = new CEnseignant; Obj1->SeDéplacer(); Obj2->SeDéplacer(); Obj3->SeDéplacer(); Obj5->SeDéplacer(); Obj9->SeDéplacer(); 420-KAB-LG Programmation orientée par objets

Les méthodes polymorphes (ou virtuelles) Idéalement, la version de la méthode utilisée devrait être déterminée par le type réel de l’objet. Pour ce faire, il faut ajouter le mot-clé virtual aux déclarations des méthodes: class CPersonne { // … virtual void SeDéplacer(); }; 420-KAB-LG Programmation orientée par objets

Méthodes polymorphes (suite) En supposant que la méthode SeDéplacer est virtuelle, déterminez la version de la méthode utilisée dans les exemples suivants: Cpersonne *Obj1 = new CPersonne; CPersonne *Obj2 = new CEtudiant; CPersonne *Obj3 = new CEnseignant; CEtudiant *Obj5 = new CEtudiant; CEnseignant *Obj9 = new CEnseignant; Obj1->SeDéplacer(); Obj2->SeDéplacer(); Obj3->SeDéplacer(); Obj5->SeDéplacer(); Obj9->SeDéplacer(); 420-KAB-LG Programmation orientée par objets

Appeler la méthode de la classe de base Pour effectuer une partie du traitement, la méthode d’une classe dérivée peut appeler la méthode de la classe de base: void CEtudiant::SeDéplacer() { // … // Pour éviter la confusion, il faut // spécifier le nom de la classe de base CPersonne::SeDéplacer(); //… } Que se passe-t-il si on oublie le CPersonne:: ? 420-KAB-LG Programmation orientée par objets

La méthode virtuelle pure et classe abstraite La méthode virtuelle pure n’a pas de définition dans la classe de base (=0) class CPersonne { virtual void SeDéplacer()=0; }; Il est donc obligatoire de redéfinir les méthodes virtuelles pures dans les classes dérivées On ne peut pas créer d’objets d’une classe qui possède une ou des méthodes virtuelles pures On dira donc de cette classe qu’elle est abstraite 420-KAB-LG Programmation orientée par objets

Exemple de polymorphisme int main() { const int N=100; CPersonne* Tab[N]; // Tableau de pointeurs for(int i=0;i<N;++i) // Le type d’objet alloué est aléatoire! if(rand()%2==0) Tab[i] = new CEtudiant(); else Tab[i] = new CEnseignant(); } // La fonction SeDéplacer change selon // le type réel de l’objet (plusieurs formes) Tab[i]->SeDéplacer(); delete Tab[i]; Ces deux simples petits lignes illustrent toute la beauté du polymorphisme! 420-KAB-LG Programmation orientée par objets

Chapitre 6 – Bibliothèque standard de C++ Les entrées / sorties (istream, ostream) Les fichiers (ifstream, ofstream) Les chaînes de caractères (string) 420-KAB-LG Programmation orientée par objets

Introduction Ensemble de classes et de fonctions standards Contient aussi la bibliothèque standard du C Contient la STL (Standard Template Library) Fait partie de la norme ISO/IEC 14882 52 modules: <cmath>, <cstdio>, <cstdlib>, <ctime>, <exception>, <fstream>, <iostream>,<istream>, <ostream>, <string>, etc. using namespace std; 420-KAB-LG Programmation orientée par objets

Hiérarchie des classes E/S 420-KAB-LG Programmation orientée par objets

Les entrés/sorties L’utilisateur du programme entre une valeur qui n’est pas autorisée: À l’extérieur des bornes. Différente du type exigé par le programme. Conséquence? Sortie du programme? Mauvais fonctionnement? Prévoir les cas d’erreur? OUI, avec les méthodes de la classe istream 420-KAB-LG Programmation orientée par objets

Flux d’entrées sorties en C++ Un flux en C++ est une zone mémoire tampon associée à un dispositif d’entrée ou de sortie qui agit comme intermédiaire entre le programme et le dispositif. Les mécanismes de tampon ont pour but d’optimiser les performances des opérations d’entrée / sortie 420-KAB-LG Programmation orientée par objets

Flux d’entrées sorties en C++ Programme Dispositif d’entrée: Clavier, fichier Données Données Zones de mémoire tampon Dispositif de sortie: Écran, fichier Données Données Flux de sortie 420-KAB-LG Programmation orientée par objets

La classe istream Déclarée dans la librairie iostream. L’objet cin est une instance de cette classe. Ses méthodes sont utilisées dans les opérations de lecture. 420-KAB-LG Programmation orientée par objets

La classe istream (méthodes) istream::get() permet de lire un caractère à la fois à partir du flux d’entrée standard. istream::ignore(int) permet d’indiquer que l’on désire ignorer, c’est à dire escamoter un certain nombre de caractères en lecture. istream::fail() permet de vérifier s’il y a eu échec lors de la dernière tentative de lecture dans le flux d’entrée. 420-KAB-LG Programmation orientée par objets

La classe istream (méthodes) istream::clear() permet de remettre à zéro (reset) les indicateurs d’état de la lecture. istream::setf(indicateur) permet de régler à vrai l’état du ou des indicateurs fournis en paramètre. istream::unsetf(indicateur) permet de régler à faux l’état du ou des indicateurs fournis en paramètre. 420-KAB-LG Programmation orientée par objets

La classe ostream Déclarée dans la librairie iostream. L’objet cout est une instance de cette classe. Ses méthodes sont utilisées dans les opérations d’écriture. 420-KAB-LG Programmation orientée par objets

La classe ostream (méthodes) ostream::put(char) permet d’écrire le caractère fourni en paramètre dans le flux de sortie standard. ostream::width(int) permet de régler la largeur de la prochaine écriture à l’écran. La largeur est fournie en paramètre et ne s’applique qu’à la prochaine écriture. ostream::fill(char) permet de fournir au flux de sortie un caractère de remplissage qui préfixera la prochaine donnée envoyée dans le flux. 420-KAB-LG Programmation orientée par objets

La classe ostream (méthodes) ostream::precision(int) permet d’établir le nombre de chiffres après le point de la prochaine valeur réelle écrite à l’écran. istream::setf(indicateur) permet de régler à vrai l’état du ou des indicateurs fournis en paramètre. istream::unsetf(indicateur) permet de régler à faux l’état du ou des indicateurs fournis en paramètre. 420-KAB-LG Programmation orientée par objets

Indicateurs Les indicateurs sont fournis en paramètre aux méthodes : istream::setf ; istream::unsetf ; ostream::setf ; ostream::unsetf sont préfixé par ios:: 420-KAB-LG Programmation orientée par objets

Indicateurs boolalpha :Affiche / lit une variable booléenne à l’aide de true et false ou de 1 et 0. dec : Affiche / lit un entier en base décimale. hex: Affiche / lit un entier en base hexadécimale. oct: Affiche / lit un entier en base octale. fixed:Affiche un réel à l’aide d’un nombre fixe de chiffres après la virgule left: Affiche la valeur à la gauche du champ à afficher right : Affiche la valeur à droite du champ à afficher showpoint :Affiche le point décimal d’un nombre réel. showpos : Affiche le signe plus (+) d’un nombre positif. skipws: Ignore les espaces blancs lors de la lecture. 420-KAB-LG Programmation orientée par objets

Fonction obsolète getch La fonction getch() En C++, cette instruction est remplacée par: cin.ignore (cin.rdbuf () -> in_avail() + 1) 1.Vider le flux d’entrée 2.Attendre qu’on appuie sur une touche 420-KAB-LG Programmation orientée par objets

La fonction getline Fonction de la librairie <string> istream& getline ( istream& is, string& str ); istream& getline ( istream& is, string& str, char delim ); Permet de lire une chaîne de caractères jusqu’à la fin de la ligne ou jusqu’à un délimiteur spécifique string Ligne; getline (cin, Ligne); getline (cin, Ligne, ‘,’); 420-KAB-LG Programmation orientée par objets

Convertir un int en string en C++ (*) string ToString(int Nombre) { stringstream ss; ss << Nombre; return ss.str(); } (*) itoa() c’est pas du C++! 420-KAB-LG Programmation orientée par objets

Convertir un string en int en C++ (*) #include <sstream> using namespace std; int ToInt(string Chaine) { int Valeur; stringstream ss; ss << Chaine; ss >> Valeur; if(ss.fail()) // Erreur } (*) atoi() c’est pas du C++! return Valeur; } 420-KAB-LG Programmation orientée par objets

Exemple 1 - Attendre void Attendre() { cout << "Appuyez sur une touche " << "pour continuer" <<endl; cin.ignore(cin.rdbuf()->in_avail()+1); } Notez le + 1 420-KAB-LG Programmation orientée par objets

Exemple 2 – Lire un entier int LireUnEntier() { int Valeur; do cout << "Donnez un entier: " << endl; cin.clear(); cin.ignore(cin.rdbuf()->in_avail()); cin >> Valeur; } while (cin.fail()); return Valeur; 420-KAB-LG Programmation orientée par objets

Exemple 3 - Afficher un réel double k = 958.943212333;   cout.setf(ios::fixed | ios::showpoint); // Attention : le fill, le precision et le // width ne s'appliquent qu'à la // prochaine écriture (jusqu'au endl) cout.fill('*'); cout.precision(3); cout.width (10); cout << k << endl; // Affiche ***958.943 420-KAB-LG Programmation orientée par objets

Ouverture d’un fichier texte Utilisation du constructeur paramétrique: const string Nom="fichier.txt"; ofstream Fichier(Nom.c_str()); Utilisation du constructeur par défaut et de la méthode open: ofstream Fichier; cin >> Nom; Fichier.open(Nom.c_str()); Prendre note du répertoire par défaut Éviter les chemins d’accès absolus Attention au \ (utiliser / ou \\) 420-KAB-LG Programmation orientée par objets

Modes d’ouverture On peut optionnellement spécifier le mode d’ouverture du fichier au constructeur paramétrique ou à la méthode open: ofstream Fichier("monfichier.dat", ios::app); ou Fichier.open("monfichier.dat", ios::app); Les modes sont : ios::app, ios::in, ios::out, ios::trunc (défaut), ios::binary Ces modes peuvent être combinés avec l’opérateur | : ios::in | ios::out | ios::app 420-KAB-LG Programmation orientée par objets

Fermeture d’un fichier Pour relire une autre fois le fichier, Pour permettre à d’autres programmes de manipuler le fichier: Fichier.close(); 420-KAB-LG Programmation orientée par objets

Lecture et écriture dans un fichier Fichier >> Mot; Ou getline(Fichier, Ligne); getline(Fichier, Ligne, Delim); ou Char = Fichier.get(); Écriture: Fichier << Infos; Méthodes utiles à l’écriture: Fichier.put, .witdh, .fill, .precision 420-KAB-LG Programmation orientée par objets

Détecter la fin d’un fichier getline (Fichier, Ligne); while ( ! Fichier.eof( ) ) { // Traiter la ligne lue // Essayer de lire la prochaine getline (Fichier, Ligne); } la détection de la fin de fichier n’est possible qu’à la suite d’une opération de lecture 420-KAB-LG Programmation orientée par objets

Indicateur d’échec getline (Fichier, Ligne); if( Fichier.fail() ) { // On récupère l’erreur // On réinitialise le flux Fichier.clear(); } 420-KAB-LG Programmation orientée par objets

Retour au début du fichier Fichier.seekg(0); Fichier.clear(); 420-KAB-LG Programmation orientée par objets

Autres méthodes La classe ifstream dérive de la classe istream: elle a donc accès à toutes les méthodes de istream: get, ignore, fail, clear, setf et unsetf La classe ofstream dérive de la classe ostream: elle a donc accès à toutes les méthodes de ostream: put, width, fill, precision, setf et unsetf La classe fstream dérive de istream et ostream!! 420-KAB-LG Programmation orientée par objets

Passer un flux en paramètre Puisque cout et un fichier en écriture sont tous les deux de la classe ostream: #include <iostream> #include <fstream> using namespace std; void AfficherBonjour(ostream& Flux) { Flux << "Bonjour" << endl; } int main() ofstream Fichier("Fichier.txt"); AfficherBonjour(cout); AfficherBonjour(Fichier); 420-KAB-LG Programmation orientée par objets

Exemple ifstream Fichier; string NomFichier; cin >> NomFichier; Fichier.open(NomFichier.c_str()); if ( ! Fichier.fail() ) { int Valeur; int Total = 0; Fichier >> Valeur; while ( ! Fichier.eof() ) Total = Total + Valeur; } cout << Total << endl; Fichier.close(); 420-KAB-LG Programmation orientée par objets

Références http://www.cplusplus.com classe ifstream classe ofstream classe fstream http://www.siteduzero.com/tutoriel-3-36367-lecture-et-ecriture-dans-les-fichiers-en-c.html 420-KAB-LG Programmation orientée par objets

Les chaînes de caractères Une suite de caractères qui prennent un sens lorsque regroupés. c h a î n e d e c a r a c t è r e s ? En C: Une suite de caractère dans un tableau (ASCIIZ) c h a î n e d r t è s ? \0 En C++: Une variable de type string (objet de classe string) string chaine = « chaîne de caractères ?» ; 420-KAB-LG Programmation orientée par objets

La classe string Déclaration de chaînes de caractères #include <iostream> #include <string> using namespace std; int main() { // Déclaration et initialisation de chaînes de caractères string Message = "Entrez votre nom : "; string Nom;   cout << Message; // Affichage à l'écran  cin >> Nom; // Lecture au clavier // Affichage d’une chaîne constante suivie de la chaîne lue au clavier cout << "Bonjour " << Nom << endl; } 420-KAB-LG Programmation orientée par objets

La classe string (4 Go de mémoire) Déclaration de chaînes de caractères // Déclaration et initialisation de chaînes de caractères en une seule étape string Message ( "Entrez votre nom :   " ); La limite de nombre de caractères dans une chaîne = 2³² - 3 caractères (4 Go de mémoire) Indice = La position du caractère dans une chaîne, il est numéroté à partir de 0 420-KAB-LG Programmation orientée par objets

2.2 Affectation de chaînes de caractères La classe string 2.2 Affectation de chaînes de caractères string Message1( "Message à écraser" ); stringsMessage2( "Message écrasant" );   cout << "Avant affectation: " << endl; cout << Message1 << endl; cout << Message2 << endl; Message1 = Message2; //Affectation cout << "Après affectation: " << endl; 420-KAB-LG Programmation orientée par objets

Affectation de chaînes de caractères La classe string Affectation de chaînes de caractères  Message1 = Message2; //Affectation OU Message1.assign (Message2); //Affectation 420-KAB-LG Programmation orientée par objets

Concaténation de chaînes de caractères La classe string Concaténation de chaînes de caractères La concaténation est une opération qui consiste à juxtaposer bout à bout deux chaînes afin de n’en former qu’une seule. “+” est l’opérateur de la concaténation. s1 + s2 est différente de s2 + s1 420-KAB-LG Programmation orientée par objets

Concaténation de chaînes de caractères La classe string Concaténation de chaînes de caractères // Déclaration et initialisation de chaînes de caractères string Chaine1( "Début" ); string Chaine2( "Fin" ); string Chaine3 = Chaine1 + Chaine2; //concaténation   cout << "La troisième chaine est : " << endl; cout << Chaine3 << endl; cout << "Voici une quatrième chaîne : " << endl; cout << ( Chaine1 + "Milieu" + Chaine2 ) << endl; 420-KAB-LG Programmation orientée par objets

Concaténation de chaînes de caractères La classe string Concaténation de chaînes de caractères “+ =” est utilisé afin d’ajouter l’opérande de droite dans l’opérande de gauche.  Message += « 123 »; OU  Message.append (« 123 »); 420-KAB-LG Programmation orientée par objets

La classe string Manipulations des caractères dans une chaînes OU string Chaine( "Début" ); Chaine[ 0 ] = 'R'; // modifier le 1er caractère ‘D’ pour ‘R’ cout << Chaine[ 2 ]; // afficher le 3ème caractère OU string Chaine( "Début" ); Chaine.at ( 0 ) = 'R'; // modifier le 1er caractère ‘D’ pour ‘R’ cout << Chaine.at ( 2 ); // afficher le 3ème caractère 420-KAB-LG Programmation orientée par objets

La classe string Remarque: Manipulations des caractères dans une chaînes Remarque: Il est important, lorsque vous tentez d’accéder à un caractère dans la chaîne, que l’indice fourni soit valide, c’est-à-dire compris entre 0 et (longueur de la chaîne - 1). Si vous ne tenez pas compte de cet avertissement, vous récolterez des problèmes!! 420-KAB-LG Programmation orientée par objets

La classe string Propriétés d’une chaîne de caractères Méthode Description length() ou size() Retourne un entier donnant le nombre de caractères. empty() Retourne true si la chaîne est vide ; false sinon. max_size() Retourne un entier donnant le nombre de caractères maximal pouvant être emmagasinés dans la chaîne (232 - 3 en VC++ ). 420-KAB-LG Programmation orientée par objets

La classe string Propriétés d’une chaîne de caractères int Longueur = Chaine.length(); // longueur de la chaine   cout << "La longueur de la chaine est : "  << Longueur << endl; bool Vide = Chaine.empty();   if (Vide) { cout << "La chaîne est vide !! " << endl; } 420-KAB-LG Programmation orientée par objets

Ordre lexicographique = ordre des caractères selon la table ASCII La classe string Comparaison de chaînes La comparaison de chaines s’effectue selon l’ordre lexicographique Ordre lexicographique = ordre des caractères selon la table ASCII La présence de caractères spéciaux dans une chaine peut produire un résultat non conforme aux attentes. 420-KAB-LG Programmation orientée par objets

== != < > <= >= La classe string Comparaison de chaînes Les opérateurs: == != < > <= >= La méthode: Chaine1.compare ( Chaine2 ); 420-KAB-LG Programmation orientée par objets

La classe string Comparaison de chaînes { if(Chaine1 == Chaine2 ) // 2 chaines égales { cout << "Les chaines sont identiques" << endl; } else if( Chaine1 != Chaine2 ) // 2 chaines différentes if( Chaine1 < Chaine2 ) cout << "La 1 est < que la 2" << endl; else cout << "La 2 est < que la 1" << endl; 420-KAB-LG Programmation orientée par objets

La classe string Comparaison de chaînes "Debut" Chaine1 Chaine2 Message affiché "Debut" "Les chaines sont identiques" "Debut " "La 2 est < que la 1" "debut" "debuts" "La 1 est < que la 2" "début" 420-KAB-LG Programmation orientée par objets

La classe string Échange de contenu entre deux chaînes de caractères Chaine1.swap( Chaine2 ); Équivalent à: string Temp; Temp = Chaine1; Chaine1 = Chaine2; Chaine2 = Temp; 420-KAB-LG Programmation orientée par objets

substr (int ind, int len) La classe string Sous-chaînes de caractères substr (int ind, int len) Méthode pour extraire une sous-chaîne de caractères contenue dans une autre. 1er argument spécifie l’indice où débute la chaîne à extraire. 2nd argument spécifie la longueur de la sous-chaîne. 420-KAB-LG Programmation orientée par objets

Rivieres La classe string Sous-chaînes de caractères Chaine = "Trois-Rivieres est une belle ville." cout << Chaine.substr( 6, 8 ) << endl; Rivieres 420-KAB-LG Programmation orientée par objets

La classe string Recherche de caractères dans une chaîne Méthode Description find() Retourne l’indice du début de la première occurrence (dans le sens de la lecture) du mot donné en argument. rfind() Retourne l’indice du début de la première occurrence (dans le sens inverse de lecture) du mot donné en argument. find_first_of() Retourne l’indice de la première occurrence de l’un des caractères donné en argument. 420-KAB-LG Programmation orientée par objets

La classe string Recherche de caractères dans une chaîne Méthode Description find_last_of() Retourne l’indice de la dernière occurrence de l’un des caractères donnés en argument. find_first_not_of() Retourne l’indice de la première occurrence d’un caractère différent de ceux donnés en argument. find_last_not_of() Retourne l’indice de la dernière occurrence d’un caractère différent de ceux donnés en argument. 420-KAB-LG Programmation orientée par objets

La classe string Recherche de caractères dans une chaîne string s(" abcdefghijklmnopqrstuvwxyz<|>allo<|>allo" );   cout << s.find( "allo" ) << endl; cout << s.rfind( "allo" ) << endl; cout << s.find_first_of( "|<>" ) << endl; cout << s.find_last_of( "|<>" ) << endl; cout << s.find_first_not_of( " abc" ) << endl; cout << s.find_last_not_of( "loa<|>" ) << endl; 30 37 27 36 4 26 420-KAB-LG Programmation orientée par objets

La classe string Effacer, remplacer et insérer des caractères dans une chaîne Méthode Description erase () Tronque la chaîne à partir d’un certain indice. replace() Remplace les occurrences d’un caractère par un autre caractère. insert() Insère une chaîne dans une autre à la position voulue. 420-KAB-LG Programmation orientée par objets

La classe string Effacer, remplacer et insérer des caractères dans une chaîne string s( "01234567890123456789" ); s.erase( 10 ); // conserve les 10 premiers caractères // Remplacer les caractères ‘ ‘ par le point ‘.’ string s( "a b c d e f g h" );   int Prochain = s.find( " " ); while( Prochain <> string::npos ) { s.replace( Prochain, 1, "." ); Prochain = s.find( " ", Prochain + 1 ); } string s ("aaaaa" ); s.insert ( 3, "!!!! " ); // Ce qui donne aaa!!!!aa 420-KAB-LG Programmation orientée par objets

Chapitre 7 – Notions avancées La surcharge des opérateurs Les exceptions Les attributs et méthodes statiques 420-KAB-LG Programmation orientée par objets

La surcharge des opérateurs Classe pour les exemples: class CBase { public: CBase(int Entier); int GetEntier() const; void SetEntier(int Entier); private: int Entier_; }; 420-KAB-LG Programmation orientée par objets

Opérateurs arithmétiques d’affectation int main() { CBase Base(10); Base += 5; // Le compilateur cherche // Base.operator+=(5) ou // operator+=(Base,5) } CBase& CBase::operator+=(int Valeur) SetEntier(GetEntier() + Valeur); return *this; 2 façons: méthodes ou fonction globale 420-KAB-LG Programmation orientée par objets

Opérateurs arithmétiques d’affectation (suite) L’opérateur retourne une référence à l’objet courant pour permettre la cascade A += B += 3 (à condition que CBase& CBase::operator+=(const CBase& Base) existe) Même opérateur sous forme de fonction globale: CBase& operator+=(CBase& Base, int Valeur) { Base.SetEntier(Base.GetEntier()+Valeur); return Base; }   420-KAB-LG Programmation orientée par objets

Questions Quelle est la définition de la méthode surchargeant l’opérateur *= ? Quelle est la définition de la fonction globale surchargeant l’opérateur *= 1. CBase& CBase::operator*=(int Valeur) { SetEntier(GetEntier() * Valeur); return *this; }  2. CBase& operator*=(CBase& Base, int Valeur) Base.SetEntier(Base.GetEntier() * Valeur); return Base; 420-KAB-LG Programmation orientée par objets

Opérateurs arithmétiques courants int main() { CBase Base1(10), Base2; Base2 = Base1 + 5; Base2 = 5 + Base1; } CBase operator+(const CBase &Base, int Valeur) CBase Nouveau(Base.GetEntier() + Valeur); return Nouveau; CBase operator+(int Valeur, const CBase &Base) Ici sous forme de fonctions globales 420-KAB-LG Programmation orientée par objets

Questions Pourquoi avons-nous utilisé des fonctions globales plutôt que des méthodes ? Que retournent ces fonctions ? Quelles sont les définitions des fonctions globales surchargeant l’opérateur * (multiplication) 1. Si on a l’exemple suivant : int i =2; CBase b(3); Cbase a = i + b;   On ne peut pas surcharger l’opérateur + de la « classe » int! Il faut donc obligatoirement implémenter l’operateur+(int,CBase) sous forme de fonction globale. 2. Un nouvel objet CBase 3. CBase operator*(const CBase &Base, int ValeurAMultiplier) { Cbase Nouveau(Base.GetEntier() * ValeurAMultiplier); return Nouveau; } CBase operator*(int ValeurAMultiplier, const CBase &Base) CBase Nouveau(Base.GetEntier() * ValeurAMultiplier); // Ou return Base * ValeurAMultiplier; 420-KAB-LG Programmation orientée par objets

Opérateurs relationnels int main() { CBase Base1(10), Base2(20); if (Base1 > Base2) //… } bool CBase::operator>(const CBase &Base) const return GetEntier() > Base.GetEntier(); 420-KAB-LG Programmation orientée par objets

Questions Aurions-nous pu écrire la surcharge de cet opérateur sous la forme d’une fonction globale? Si oui, comment ? Sinon, pourquoi ? Quelle est la définition de la méthode surchargeant l’opérateur == ? Quelle est la définition de la fonction globale surchargeant l’opérateur == ? 1. Oui! bool operator>(const CBase &Base1, const CBase &Base2) { return Base1.GetEntier() > Base2.GetEntier(); } 2. bool CBase::operator==(const CBase &Base) const return GetEntier() == Base.GetEntier(); 3. bool operator==(const CBase &Base1, const CBase &Base2) return Base1.GetEntier() == Base2.GetEntier();   420-KAB-LG Programmation orientée par objets

Opérateur d’affectation int main() { CBase Base1(10), Base2; Base2 = Base1; } CBase& CBase::operator=(const CBase &Base) SetEntier(Base.GetEntier()); return *this; 420-KAB-LG Programmation orientée par objets

Questions Que retourne cette méthode ? Aurions-nous pu écrire la surcharge de cet opérateur sous la forme d’une fonction globale? Si oui, comment ? Sinon, pourquoi ? Modifiez la définition de la méthode surchargeant l’opérateur = pour prévoir le cas où le programme contient l’instruction Base1 = Base1; Dans quel cas la protection élaborée à la question précédente est-elle obligatoire ? 1. Une référence à CBase 2. Non ! Car operator= trop important : fait parti de la trinité… 3. CBase& CBase::operator=(const CBase &Base) { if(this!=&Base) SetEntier(Base.GetEntier()); } return *this; 4. Dans le cas de l’allocation dynamique, il faut éviter de détruire le tableau!!!   420-KAB-LG Programmation orientée par objets

Opérateur d’insertion de flux int main() { CBase Base1(10); cout << Base1; } ostream & operator<<(ostream & Flux, const CBase & Base) Flux << Base.GetEntier(); return Flux; 420-KAB-LG Programmation orientée par objets

Questions Que retourne cette méthode ? Aurions-nous pu écrire la surcharge de cet opérateur sous la forme d’une méthode ? Si oui, comment ? Sinon, pourquoi ? 1. Une référence au ostream pour faire la cascade: cout << " allo " << oBase1 << 2; 2. Non! On ne peut pas modifier le contenu de la classe ostream! 420-KAB-LG Programmation orientée par objets

Opérateurs d’incrémentation et de décrémentation int main() { CBase Base(10); cout << ++Base; // Affiche 11 cout << Base++; // Affiche 11 }  CBase & CBase::operator++() // forme préfixée ++i SetEntier(GetEntier()+1); return *this; CBase CBase::operator++(int) // forme suffixée i++ CBase Temp(*this); return Temp; 420-KAB-LG Programmation orientée par objets

Questions Quel est le rôle du paramètre fictif ? Laquelle des deux versions est la plus rapide ? Quelles sont les définitions des méthodes surchargeant l’opérateur -- 1. Distinguer entre ++i (forme préfixée) et i++ (forme suffixée) 2. ++i (forme préfixée) pas de copie! 3. CBase & CBase::operator--() // forme préfixée { SetEntier(GetEntier()-1); return *this; }   CBase CBase::operator--(int) // forme suffixée CBase Temp(*this); return Temp; 420-KAB-LG Programmation orientée par objets

Résumé Opérateurs sous forme de méthodes: Exemples: Accès à tous les attributs de la classe On doit pouvoir modifier la déclaration de la classe (impossible pour ostream par exemple) L’opérateur = ne peut être déclaré que sous la forme d’une méthode Exemples: CBase& operator+=(int ValeurAAjouter); CBase operator+(int ValeurAAjouter); bool operator>(const CBase &Base) const CBase& operator=(const CBase &Base); CBase& operator++(); CBase operator++(int); 420-KAB-LG Programmation orientée par objets

Résumé (suite) Opérateurs sous forme de fonctions globales: Accès aux attributs publics seulement Dans le cas où on ne peut pas modifier la déclaration de la classe L’opérateur << ne peut être déclarée que sous la forme d’une fonction non membre Exemples: CBase& operator+=(CBase& Base, int ValeurAAjouter); CBase operator+(int ValeurAAjouter, const CBase& Base); bool operator>(const CBase& Base1, const CBase& Base2); ostream & operator<<(ostream& Flux, const CBase& Base); 420-KAB-LG Programmation orientée par objets

Opérateurs pouvant être surchargés , ! != % %= & && &= () * *= + ++ += – –– –= –> –>* / /= < << <<= <= = == > >= >> >>= [] ^ ^= | |= || ~ delete new Et les opérateurs de conversion: operator const char *() { Chaine_[iTaille_]=0; return Chaine; } 420-KAB-LG Programmation orientée par objets

Opérateurs ne pouvant pas être surchargés . .* :: ?: sizeof   420-KAB-LG Programmation orientée par objets

Référence http://www.siteduzero.com/tutoriel-3-11199-la-surcharge-d-operateurs.html 420-KAB-LG Programmation orientée par objets

La gestion des erreurs et les exceptions 420-KAB-LG Programmation orientée par objets 420-KAB-LG Programmation orientée par objets 217 217

La gestion des erreurs par messages void CFruit::SetPoids(int Poids) { if(Poids>0) Poids_=Poids; else cout << "Poids invalide" << endl; } Il n’y a pas toujours une console pour afficher les erreurs! Utiliser un fichier? Utiliser des boîtes de message? Impossible pour le programme de récupérer d’une erreur! 420-KAB-LG Programmation orientée par objets

La gestion des erreurs par codes de retour int CFruit::SetPoids(int Poids) { if(Poids>0) Poids_=iPoids; else return ERREUR; } C’est le cas de beaucoup de librairies Monopolise la valeur de retour Fonction appelante doit vérifier le code de retour (alourdit les programmes) Que faire pour les constructeurs? Que faire pour les destructeurs? 420-KAB-LG Programmation orientée par objets

Les exceptions Façon standard de gérer les erreurs en C++ Simplifie la gestion des erreurs Trois (3) mots-clés intégrés au C++ pour gérer les erreurs: throw: lancer une erreur try: définir une zone de code où une erreur peut survenir catch: attraper et traiter une erreur 420-KAB-LG Programmation orientée par objets

throw On signale ou on « lance » une exception avec throw Une exception est tout simplement un objet. Il peut être de la classe int, string, exception ou autre int CFruit::SetPoids(int Poids) { if(Poids>0) Poids_=Poids; else throw -1; // ou throw string("Poids invalide");   // ou throw CTomate(); } Notez bien la syntaxe! 420-KAB-LG Programmation orientée par objets 420-KAB-LG Programmation orientée par objets 221

throw (suite) Lorsqu’une exception est lancée: Les variables locales sont détruites (appel des destructeurs pour les objets) La fonction en cours est arrêtée L’exception est relancée à la fonction appelante et ce, tant et aussi longtemps que l’exception n’est pas traitée Si l’exception remonte jusqu’au main et n’est pas traitée par celui-ci, le programme arrête brutalement. 420-KAB-LG Programmation orientée par objets

try On teste des instructions sensibles avec le bloc try: { UnFruit.SetPoids(-1); cout << UnFruit.GetPoids(); } Si une instruction lance une erreur: le bloc try est arrêté le programme saute au prochain bloc catch qui traite la classe d’exception lancée 420-KAB-LG Programmation orientée par objets 420-KAB-LG Programmation orientée par objets 223

catch L’exécution du programme est reprise après le bloc catch On traite une classe d’exceptions avec le bloc catch: catch(int i) { cout << "Erreur:" << i; } catch(const string& s) { cout << "Erreur:" << s; } catch(const exception& e) { cout << "Erreur:" << e.what(); } On traite toutes les classes d’exceptions avec la syntaxe suivante: catch(...) { cout << "Erreur!"; } L’exécution du programme est reprise après le bloc catch 420-KAB-LG Programmation orientée par objets 420-KAB-LG Programmation orientée par objets 224

Exemple int division(int a, int b) { if(b==0) throw string("ERREUR : Division par zéro !"); return a/b; } int main() int a,b; cin >> a; cin >> b; try cout << division(a, b) << endl; catch(const string& chaine) cout << chaine << endl; 420-KAB-LG Programmation orientée par objets

Relancer une exception On peut relancer une exception (pour en terminer le traitement par exemple) de la façon suivante: catch(const exception& e) { // On traite une première fois cerr << "ERREUR: " << e.what(); // On relance l'exception au prochain bloc catch throw; } 420-KAB-LG Programmation orientée par objets

Le spécificateur d’exception Indique les classes d’exceptions que la méthode peut lancer Uniquement une exception de classe exception: void methode1() throw(exception); Un string ou un int void methode2() throw(string,int); Aucune exception: void methode3() throw(); N'importe quel type d'exception: void fonction4(); Le spécificateur d’exception n’est pas implémenté par VS 2008 et 2010! On a donc le warning suivant: warning C4290: Spécification d'exception C++ ignorée Pour désactiver ce warning: #pragma warning( disable : 4290 )  420-KAB-LG Programmation orientée par objets

Les exceptions standards La classe exception (librairie exception) est la classe de base de toutes les exceptions lancées par la bibliothèque standard (namespace std) On peut créer nos propres classes d’exceptions en les dérivant de la classe exception La bibliothèque standard peut lancer des exceptions des classes bad_alloc, bad_cast, bad_exception, bad_typeid, ios_base::failure On peut utiliser les classes définies dans la librairie stdexcept: domain_error, invalid_argument, length_error, out_of_range, logic_error, range_error, overflow_error, underflow_error, runtime_error 420-KAB-LG Programmation orientée par objets

Les variables statiques Variable qui existe en un seul exemplaire Valeur commune à toutes les instances (shared) Variable de classe (par opposition à variable d’instance) La variable statique est créée au démarrage du programme et non à la création d’une instance 420-KAB-LG Programmation orientée par objets

Déclaration (.h) class CAvecStatiques { public: int Attrib_; static int Stat_; static const int STATCONST; }; 420-KAB-LG Programmation orientée par objets

Définition (.cpp) Il faut inclure la déclaration Enlever les static Spécifier la classe #include "AvecStatiques.h" int CAvecStatiques::Stat_ = 0; const int CAvecStatiques:: STATCONST = 5; 420-KAB-LG Programmation orientée par objets

Utilisation CAvecStatiqes X, Y; X.Stat_ = 3; cout << X.Stat_; // affiche 3 cout << Y.Stat_; // affiche 3 Y.Stat_ = 5; cout << X.Stat_; // affiche 5 cout << Y.Stat_; // affiche 5 CAvecStatiqes::Stat_ = 7; cout << CAvecStatiqes::Stat_; // Affiche 7 Il n’est pas nécessaire d’avoir un objet pour accéder à une variable statique!! 420-KAB-LG Programmation orientée par objets

La méthode statique Méthode qui peut être appelée sans objet ce qui implique que la méthode ne peut utiliser que des variables et des méthodes statiques Déclaration class CAvecStatiques { public: static void MethodeStatique(); }; 420-KAB-LG Programmation orientée par objets

La méthode statique (suite) void CAvecStatiques::MethodeStatique() { cout << Stat_; } int main() CAvecStatiqes X; CAvecStatiqes::Stat_ = 9; X.MethodeStatique(); // Affiche 9 // Affiche 9 CAvecStatiqes::MethodeStatique(); 420-KAB-LG Programmation orientée par objets

Utilisation typique: Le compteur d’instances // Lapin.h class CLapin { static int NbLapins_; public: Clapin::Clapin() { NbLapins++; } Clapin::~Clapin() { NbLapins--; } static int GetNbLapins() { return NbLapins_; } }; // Lapin.cpp int CLapin::NbLapins_ = 0; // main.cpp int main() { CLapin A,B,C; // Affiche 3 cout << Clapin::GetNbLapins(); } 420-KAB-LG Programmation orientée par objets

Utilisation typique: Le singleton class X { static X Singleton_; X(){}; // constructeur privé public: static X& GetSingleton() { return Singleton_; } }; X X::Singleton_; // Dans le cpp // Utilisation: X::GetSingleton().Methode() 420-KAB-LG Programmation orientée par objets