Professional Documents
Culture Documents
Plan du document
De la programmation classique la POO Avantages de la POO Exemples dobjets Objet logiciel
tat Comportement Identit
Concept de classe
Catgorie Classe Instance Constructeur
Hritage Association
Programmation << classique >> Objectif : crire une squence d'instructions de telle faon qu'un ordinateur produise une sortie approprie pour une certaine entre Ingrdients :
dcomposition fonctionnelle variables passages de paramtres tests boucles structures
Dcomposition fonctionnelle Le programme est une fonction principale int main(argc, argv[]) Cette fonction appelle des sous-fonctions Qui en appellent d'autres
main()
init()
calcule()
trie()
affiche() permute()
factorise()
compare()
Tous les ingrdients de la programmation procdurale classique sont prsents Mais la dcomposition fonctionnelle n'est pas assez structurante pour des programmes trs complexes Structurer le programme autour des objets manipuls Les traitements sont associs aux objets Sparation plus claire entre donnes et traitements
init()
calcule() Donnes
init()
calcule() factorise()
trie()
compare() permute()
Habituellement, un programme c'est une suite d'instructions. L'ordinateur est trs bte et il faut tout lui dtailler. Exemple programme douverture de porte
Mettre la main sur la poigne de la porte Tourner la poigne Pousser la porte Mettre le doigt sur l'interrupteur Appuyer sur l'interrupteur pour allumer l'ampoule
Tout se passe trs bien. Mais qu'est-ce qui se passe par exemple si on met une porte automatique ? Le programme sera incapable de trouver la poigne et d'ouvrir la porte !
En programmation objet, on associe aux objets des actions (aussi appelles mthodes). Par exemple, l'objet porte on peut associer la mthode ouvrir. De mme pour l'ampoule on pourrait associer une mthode allumer, teindre, etc. Le programme devient plus simple:
porte.ouvrir ampoule.allumer
On a plus besoin de savoir comment la portes'ouvre. On se contente de l'ouvrir. Pour indiquer qu'on applique la mthode (ouvrir) sur l'objet (porte), on note souvent objet.mthode (ici : porte.ouvrir).
Bien sr il faut dtailler ce que fait la mthode ouvrir de porte et la mthode allumer de lumire. On ne va pas dtailler dans le programme ce que fait la mthode ouvrir, mais on va le dtailler dans l'objet lui-mme. C'est normal, puisque la mthode ouvrir ne s'applique qu' la porte, pas la lumire:
On peut changer la porte en mettant une porte automatique. On peut aussi l'ouvrir (mme si la porte elle-mme ne s'ouvre pas de la mme faon):
porte.ouvrir: Se placer devant la porte Attendre que la porte soit compltement ouverte
Mais votre programme pourra l'ouvrir sans rien changer: porte.ouvrir ampoule.allumer Le programme principal : il est inchang malgr le changement de porte
Les objets peuvent tre modifis sans avoir modifier votre programme (c'est aussi le cas ici).
Les objets sont facilement rutilisables dans de nouveaux programmes. Les langages objets offrent des mcanismes pour permettre ce genre de programmation.
parle odie poursuit Dupond java 2 45BEJ91 0203040506 Dupont poursuit felix
001-DF-YTR 007BEJ06
Objet logiciel
Abstraction
Reprsentation abstraite des entits du monde rel ou virtuel dans le but de les piloter ou de les simuler
Programme, logiciel
Service
Objet =
tat
tat +
Comportement + Identit unObjet
Tlphone portable
voirRpertoire()
tat
monTlphone
tat
Identit Valeurs instantanes de tous les attributs dun dobjet objet attribut volue au cours du temps compte001 : CompteBancaire Dpend variable de lhistoire de lobjet solde DEBITAUTORISE attribut
constant
1000
1000
Classe
Description dune famille dobjets
Mmes attributs Mme mthodes
Spcification
Ralisation (implantation)
Dcrit comment la spcification est ralise
Classe CompteBancaire
CompteBancaire
Nom de la classe
CompteBancaire
solde
dposer() retirer()
attributs
oprations
Instance
Chaque objet appartient une classe Relation dinstanciation instance de
CompteBancaire
<<instanciation>> compte001 : CompteBancaire
Constructeur
Un objet doit tre cr au sein dune classe == moule Mthode particulire : constructeur
Construit lobjet avec ses attributs, ses mthodes Initialise les valeurs des attributs Nom du constructeur = Nom de la classe CompteBancaire Nom de la classe
Constructeur
attributs
oprations
Gnralisation et spcialisation
Gnralisation
Factoriser les lments communs (attributs, oprations...) dun ensemble de classes
Simplifier les diagrammes (regroupements smantiques) ClasseMre
Spcialisation
Gnralisation
Spcialisation
Utiliser les caractristiques d'une classe dj identifie et en spcifier de nouvelles.
ClasseFille
Hirarchie de classe
Arborescence des hritages
Gnralisation
CompteChque
montantDcouvAutoris
CompteEpargne
taux intrts
solde
changerDecouvert ()
solde
calculerIntrts () crditerIntrts () changerTaux ()
dposer () retirer ()
dposer () retirer ()
Gnralisation
CompteBancaire solde dposer () retirer()
est diffrente
CompteCheque
montantDcouvertAutoris
CompteEpargne
taux intrts calculerIntrts () crditerIntrts () changerTaux ()
changerDecouvert ()
retirer ()
Spcialisation
Un PlanEpargneLogement est un CompteEpargne ayant des caractristiques propres
PlanEpargneLogement dure dateDebut priodiciteVersement montantVersement calculerMontantPrt() retirer() CompteEpargne taux intrts calculerIntrts () crditerIntrts () changerTaux ()
PlanEpargneLogement
Arborescence d'hritage
CompteBancaire solde dposer () retirer() CompteEpargne taux intrts calculerIntrts () crditerIntrts () changerTaux () PlanEpargneLogement dure dateDebut priodiciteVersement montantVersement calculerMontantPrt() retirer()
CompteChque
montantDcouvAutoris
changerDecouvert () retirer ()
retirer ()
retirer ()
class PlanEpargneLogement public CompteBancaire { void retirer ( double montant ) { cout <<" Interdit !! "; } }
Association
Agence
grer
Client possder
Compte
Un et un seul Zro ou un De M N (entiers naturels) De zro plusieurs De zro plusieurs D'un plusieurs
* 500
BNP EVRY
indice 0
500
unClient:Client
grer
possder
vieillir() changerNom(...)
Meilleur C
Le langage C++ se veut un langage C amlior. Il possde des fonctionnalits supplmentaires, et notamment * la surcharge de fonctions * le passage par rfrence * l'emplacement des dclarations * l'allocation dynamique Les apports spcifiques de C++ sont * l'aide l'abstraction de donnes: dfinition de types de donnes, et de leur implmentation concrte. * l'aide la programmation objet: hirarchie de classes et hritage.
Entres-sorties
Les entres et sorties sont gres dans C++ travers des objets particuliers appeles streams ou flots. Inclure <iostream.h> Deux oprateurs sont surchargs de manire approprie pour les flots: * l'oprateur d' insertion << (criture) * l'oprateur d' extraction >> (lecture) Trois flots prdfinis sont * cout attach la sortie standard; * cerr attach la sortie erreur standard; * cin attach l'entre standard;
E/S exemple 1
#include <iostream.h> main() { cout << "Bonjour, monde !\n"; } Plusieurs expressions: cout << ex_1 << ex_2 << ... << ex_n ; Plusieurs ''lvalues'': cin >> lv_1 >> lv_2 >> ... >> lv_n ; Les types crits ou lus sont char, short, int, long, float, double, char* Exemple #include <iostream.h> int i; main() { cout << "Un entier : "; cin >> i; cout << "Le carre de " << i <<" est " << i*i << endl; }
Commentaires
/* commentaire // commentaire commentaire */ // commentaire
Rfrences Constantes
Passage par rfrence constante pour ne pas copier l'argument l'appel; ne pas modifier l'argument : void afficher(const objet&); Passage par rfrence constante permet d'assurer l'encapsulation en vitant la copie sur la pile de structures trop grande.
Surcharge
Un mme identificateur peut dsigner plusieurs fonctions, si elles diffrent par la liste des types de leurs arguments. float max(float a, float b) { return (a > b) ? a : b;} float max(float a, float b, float c) { return max(a, max(b, c));} float max(int n, float t[]) { if (!n) return 0; float m = t[0]; for (int i = 1 ; i < n; i++) m = max(m, t[i]); return m; } void main() { float x, y, z; float T[] ={11.1, 22.2, 33.3, 44.4, 7.7, 8.8 }; x = max (1.86, 3.14); y = max (1.86, 3.14, 37.2); z = max (6, T); cout << x <<" "<< y <<" "<< z; }
Allocation dynamique
Deux Oprateurs Intgrs au langage. Les oprateurs new et delete grent la mmoire dynamiquement. new chose[n] alloue la place pour lments de type chose et retourne l'adresse du premier lment; delete addresse libre la place alloue par new. int* a = new int; // malloc(sizeof(int)) double* d = new double[100]; // malloc(100*sizeof(double))
Fonctions/Mthodes en ligne
Une fonction en ligne (inline) est une fonction dont les Instructions sont incorpores par le compilateur dans le module objet chaque appel. Donc il n'y pas d'appel : gestion de contexte, gestion de pile; Dclaration par qualificatif inline. inline int sqr(int x) { return x*x; } [ les mthodes dfinie dans le corps de classe sont inlines] [ les fonctions trop grandes ou rcursives ne sont pas inlines]
Classes et objets
Une classe est une structure, dont les attributs sont des donnes ou des mthodes. Un objet, ou une instance, est un exemplaire de cette structure. class Complexe { public: float re, im;//donnes void show(); //mthode }; On dclare des objets de la classe par: Complexe a, b; On les manipule de manire usuelle: a.re = b.im; b.re = 7; a.show();
La dfinition d'une mthode se fait soit en ligne, soit sparment; dans le deuxime cas, elle utilise l' oprateur de porte not :: pour dsigner la classe. void Complexe::show() { cout << re << ' ' << im; } A l'appel a.show(), la mthode est celle de la classe de a, donc Complexe::show(), et les champs re et im sont ceux de l'objet appelant, c'est--dire a.re et a.im.
La surcharge d'oprateurs permet de dfinir une forme agrable pour des oprations sur des objets. Complexe operator+(Complexe s, Complexe t) { Complexe w; w.re = s.re + t.re; w.im = s.im + t.im; return w; } On peut alors crire : Complexe a, b, c; ... a = b + c;
Classes
1. Objectif 2. Dclaration 3. Dfinition 4. Encapsulation 5. Constructeurs 6. Une classe de complexes 7. Une classe de rationnels 8. Surcharge d'oprateurs 9. Liste d'initialisation 10. Membres statiques 11. Mthodes constantes 12. La classe string
Objectifs
Une classe est la description d'une famille d'objets ayant mme structure et mme comportement. Une classe regroupe un ensemble d'attributs ou membres, rpartis en *un ensemble de donnes *un ensemble de fonctions, appeles mthodes.
Avantages !!! * simplifie l'utilisation des objets, * rapproche les donnes et leur traitement: c'est l'objet qui sait le mieux comment grer une demande, * renforce la robustesse du programme et la structure * simplifie la maintenance et la construction * permet l'encapsulation : possibilit de ne montrer de l'objet que ce qui est ncessaire son utilisation. * (permet de) masquer l'implmentation
La dclaration d'une classe donne la nature des membres (type, signature), et les droits d'accs: public, protected, private (dfaut). La dfinition d'une classe fournit la dfinition des mthodes. L'encapsulation peut se pratiquer en donnant l'utilisateur * un fichier en-tte contenant la dclaration de la classe; * un module objet contenant la version compile du fichier contenant la dfinition de la classe.
Dclaration
La syntaxe est celle des structures. Une struct est une classe dont tous les attributs sont publics. class Point { int x, y; public: void setPoint (int, int); void deplace (int, int); void affiche (); }; * La classe Point a deux membres donnes privs x et y. * Elle a trois mthodes publiques setPoint, deplace et affiche.
Dfinition
L' oprateur de porte :: indique la classe laquelle appartient la mthode. void Point::setPoint(int a, int b) { x = a; y = b ; } void Point::deplace (int dx ,int dy) { x += dx; y += dy; } void Point::affiche() { cout << "x = " << x <<" , y = " << y << endl; }
Les champs x, y invoqus dans les mthodes sont ceux de l'objet qui appelle la mthode. Cet objet est explicitement accessible par le pointeur this. On peut crire void Point::setPoint(int a, int b) { this -> x = a; this -> y = b ; }
Utilisation
void main() { Point a, b; a.setPoint(1, 2); b.setPoint(3,-5); a.affiche(); // x = 1, y = 2 b.affiche(); // x = 3, y = -5 a.deplace(1,1); a.affiche(); // x = 2, y = 3 }
Encapsulation
Principe de programmation : Il s'agit de ne montrer l'utilisateur que ce qui lui est destin. * seules des fonction d'accs et de modification sont rendues publiques; * toute donne est prive ou protge; * l'implmentation peut ntre disponible que par un module objet. Exemple: Le projet est compos de trois fichiers * Un fichier point.h de dclaration de la classe Point * Un fichier point.c d'implmentation des mthodes de la classe * Un fichier main.c d'utilisation. Le fichier d'implmentation est terme remplac par un module objet point.o
// Fichier point.h class Point { int x, y; public: Point (int, int); void deplace (int, int); void affiche (); };
// Fichier point.c #include <iostream.h> #include "point.h" Point::Point(int a, int b) { x = a; y = b ; } void Point::deplace (int dx , int dy) { x += dx; y += dy; } void Point::affiche() { cout << "x = " << x <<" , y = "<< y << endl; }
// Fichier main.c #include "point.h" void main() { Point a(1,2), b(3,-5); a.affiche(); b.affiche(); a.deplace(1,1); a.affiche(); }
Constructeurs
Les constructeurs permettent de dfinir les initialisations possible des instances d'une classe. * En C++, un constructeur a le nom de la classe, et pas de type de retour. * Une classe peut avoir plusieurs constructeurs. * Un constructeur sans arguments est appel constructeur par dfaut. - ce constructeur existe implicitement, s'il est le seul constructeur. - la dfinition d'un deuxime constructeur exige que l'on dfinisse explicitement le constructeur par dfaut si l'on veut s'en servir.
Le constructeur par dfaut est utilis * lors de la dfinition d'un objet, par X x; * lors d'une allocation, par px = new X; Sauf criture explicite, le constructeur par dfaut n'effectue pas d'action.
Destructeur
Le destructeur est not ~X() pour une classe X. Il est utilis * lorsque le programme quitte le bloc o l'objet est dclar * pour la destruction explicite par delete px; Le destructeur permet de spcifier ce qui doit tre fait quand l'objet est dsallou. Ceci est important quand un constructeur fait de l'allocation explicite.
Exemple constructeur
Remplacement de la mthode setPoint par un constructeur : class Point { int x, y; public: Point (int, int); void deplace (int, int); void affiche (); }; Le constructeur Point(int,int) rend inoprant le constructeur par dfaut s'il n'est pas redfini. Le constructeur est employ en passant les arguments en paramtre. C'est une abrviation de Point a = Point(1.5,2.5), b = Point(3,-5); Point::Point(int a, int b) { x = a; y = b ; }... void main() { Point a(1.5,2.5), b(3,-5); ... }
Variations * Un constructeur simple peut tre dfini en ligne, par class Point { int x, y; public: Point (int a, int b) {x = a; y = b;} ... }; * Au lieu de construire l'objet puis d'affecter des valeurs aux champs, on peut initialiser les champs avec les valeurs, par Point (int a, int b) : x(a), y(b) {}
Tableaux d'Objets
Tableaux d'objets attention le constructeur par dfaut est appel sur chaque lment du tableau. main () { const int taille = 7; Point* a = new Point[taille]; // par defaut for (int i=0; i < taille ; i++) cout << i << a[i].x << a[i].y << endl; delete [] a; } La libration d'un tableau d'objets par delete [] * parcourt le tableau et appelle le destructeur sur chaque lment du tableau; * puis libre le tableau.
Construction&Destruction
La mention explicite du constructeur par dfaut et du destructeur signifie leur redfinition. class Id { string nom; public: Id() { cout << "Entrez votre nom : ";cin >> nom;} ~Id(){ cout <<"Mon nom est "<< nom <<endl; } }; Le programme se rduit : Ou: void main() Id pierre,paul; { void main(){} Id pierre, paul; } Voici une trace d'excution: Entrez votre nom : Pierre Entrez votre nom : Paul Mon nom est Paul Mon nom est Pierre
En utilisant les arguments par dfaut, les trois constructeurs se rduisent en un seul. Ici, on remplace l'affectation par l'initialisation, et on ajoute une mthode: class Complexe { double re, im; Complexe(double r = 0, double i = 0) : re(r), im(i) {} double getModule() { return sqrt(re*re + im*im); } } On s'en sert * l'initialisation, par exemple Complexe h, a(3,5), b = Complexe(2,4); Complexe c(5), d = Complexe(6), e = 7; Par conversion de type, 7 est transform en Complexe(7) puis copi.
// Implmentation Complexe::Complexe(double re, double im): re(re), im(im){} double Complexe::getRe() { return re; } double Complexe::getIm() { return im; } double Complexe::getModule() { return sqrt(re*re+im*im); } void Complexe::setRe(double x) { re = x; } void Complexe::setIm(double y) { im = y; } // Utilisation void main() { Complexe a = Complexe(3,4); cout << a.getModule() << endl; a.showXY(); a.setRe(20); a.setIm(20); cout << a.getModule() << endl; a.showXY(); Complexe b(5); cout << b.getModule() << endl; b.showXY();
Les rationnels
L'objectif est de montrer l'utilisation de surcharges, cette fois-ci sur les oprateurs arithmtiques et d'entre-sortie. -3547/977777 0/1 etc Un nombre rationnel est toujours rduit, et le dnominateur est toujours strictement positif. D'o la ncessit d'une mthode de rduction. [rduit: numrateur et dnominateur sont des entiers premiers entre eux, c-a-d les plus petits possibles.]
class Rat { static int pgcd(int,int); public: int num, den; void red(); // reduit la fraction Rat(int n = 0) : num(n), den(1) {} Rat(int n, int d) : num(n), den(d) { red();} }; La rduction fait appel une fonction de calcul de pgcd: void Rat::red() { int p = pgcd( (num > 0) ? num : -num, den); num /= p; den /= p; } int Rat::pgcd(int a, int b) { return (!b) ? a : pgcd(b, a%b); } Une mthode dclare static (Mthode de classe) * peut tre appele sans rfrence une instance * peut tre appele par rfrence sa classe * n'a pas de pointeur this associ. Une donne dclare static (Donne de classe) est commune toutes les instances, une seule allocation et donc une seule valeur.
Nous dfinissons les quatre oprations arithmtiques par: Rat operator+(Rat a, Rat b) { return Rat(a.num*b.den + a.den*b.num, a.den*b.den); } Rat operator-(Rat a, Rat b) { return Rat(a.num*b.den - a.den*b.num, a.den*b.den); } Rat operator/(Rat a, Rat b) { return Rat(a.num*b.den, a.den*b.num); } Rat operator*(Rat a, Rat b) { return Rat(a.num*b.num, a.den*b.den); } Le moins unaire se dfinit par: Rat operator-(Rat a) { return Rat(-a.num, a.den); }
Les rationnels pass en argument ne sont pas modifis, on peut donc les spcifier const Rat&. Rat operator+(const Rat& a, const Rat& b) {...} Rat operator-(const Rat& a, const Rat& b) {...} ... L'oprateur d'incrmentation += se surcharge galement: Rat& operator+=(Rat& a, const Rat& b) { a.num = a.num*b.den + a.den*b.num; a.den = a.den*b.den; a.red(); return a; } L'un des appels a += b; //ou operator+=(a,b); * construit dans a pass par rfrence, la valeur incrmente, * et en transmet la rfrence en sortie. Ici, une dfinition en mthode est plus logique
Copie et affectation
1. Constructeurs 2. Constructeur de copie 3. Affectation 4. Conversions La copie et l'affectation sont des opration trs importante.
Constructeurs
Les constructeurs se classent syntaxiquement en 4 catgories 1. le constructeur par dfaut, sans argument, 2. les constructeurs de conversion, un argument 3. le constructeur de copie, un argument 4. les autres constructeurs.
constructeur de conversion
Un constructeur de conversion sert souvent la promotion. Exemple: class Rat { int num, den; public: ... Rat(int n) { num = n; den = 1;} ... }; On s'en sert pour la conversion Rat r, s; ... r = s + 7; L'entier 7 est promu en Rat(7) avant l'addition.
Constructeur de copie
Chaque classe possde un constructeur de copie (ne pas confondre avec l'oprateur d'affectation). Le constructeur de copie par dfaut copie membre membre en utilisant le constructeur de copie de chaque membre, et une copie bit bit pour les types de base (copie superficielle). Ceci est insuffisant en prsence d'adresses. Il faut alors allouer de nouvelles zones mmoire (copie profonde).
Le constructeur de copie est utilis * lors d'une initialisation: X x = y; X x(y); X* x = new X(y); o y est un objet dj existant. * lors du retour d'une fonction retournant un objet par valeur; * lors du passage d'un objet par valeur une fonction. Le constructeur de copie a deux prototypes possibles : X (X&); X (const X&); L'argument est donc un objet de la classe X pass par rfrence (videmment !) et ventuellement spcifi comme Non modifiable dans le constructeur.
Voici une classe Pt possdant: * Un constructeur de copie Pt(const Pt& p) * Un oprateur d'affectation Pt& operator=(const Pt& p) #include <iostream.h> class Pt { int x, y; public: Pt(int abs = 1, int ord = 0): x(abs), y(ord) {} //implantation par dfaut: Pt(const Pt& p) : x(p.x), y(p.y){} //implantation par dfaut: Pt& operator=(const Pt& p) { x = p.x; y = p.y; return *this; } };
Affectation
L'affectation et la copie sont des oprations diffrentes. * le constructeur de copie sert l'initialisation et pour le passage de paramtres. Il construit l'objet. * l'oprateur d'affectation = pour l'affectation dans une expression. Il retourne un objet ou une rfrence. L'oprateur d'affectation est un oprateur, et peut donc tre redfini explicitement par une fonction operator=(). Chaque classe possde un oprateur d'affectation par dfaut. L'affectation est superficielle comme la copie, et consiste en une affectation membre membre.
La signature de l'oprateur est X& operator=(X&) X& operator=(const X&) X operator=(X&) X operator=(const X&) et l'expression y = x quivaut y.operator=(x) Le rsultat de l'affectation est donc dans l'objet appelant.
Fonctions amies
L'amiti permet d'accder aux parties prives. Une ''dclaration d'amiti'' incorpore, dans une classe X, les fonctions autorises accder aux membres privs. Une fonction amie a le mme statut qu'une fonction membre de X. Fonction globale class X { ... friend f(X); } Ici, f est autorise accder aux membres privs de la classe X.
Fonction membre de Y class Y { ... void f(X& x); } class X { ... friend Y::f(X& x); } void Y::f(X& x) { x.priv = 1; // ok x.prot = 1; // ok x.publ = 1; // ok } Une classe entire est une classe amie par class X { ... friend class Y; }
Oprateurs amis
Une fonction amie d'une classe a les mmes droits qu'une fonction membre, et en particulier peut accder aux membres privs de la classe. class Rat { int num, den; // prives public: int getNum() {return num;} int getDen() {return den;} Rat(int n = 0, int d = 1) : num(n), den(d) {} };
L'addition Rat operator+(const Rat& a, const Rat& b) { int n = a.getNum()*b.getDen() + a.getDen()*b.getNum(); return Rat(n, a.getDen()*b.getDen()); } s'crit plus efficacement et plus lisiblement: Rat operator+(const Rat& a, const Rat& b) { return Rat(a.num*b.den + a.den* b.num, a.den*b.den); } Or num et den sont privs. Pour les rendre accessibles, l'oprateur est dclar ami, dans la dclaration de la classe Rat, par friend Rat operator+(Rat, Rat); Une fonction amie a les mmes droits qu'une fonction membre.
Syntaxe
Un oprateur est unaire, binaire. Un oprateur peut tre dfini * soit comme fonction globale un ou deux arguments * soit comme fonction membre avec un argument de moins. La syntaxe est * oprateur binaire au niveau global: type operatorop(type,type); Rat operator+(Rat,Rat); L'expression u+v quivaut operator+(u,v). * oprateur binaire membre de classe: type operatorop(type); Rat& operator+=(Rat); L'expression u += v quivaut u.operator+=(v).
* oprateur unaire au niveau global: type operatorop(type); Rat operator-(Rat); L'expression -u quivaut operator-(u). * oprateur unaire membre de classe: type operatorop(); Rat operator-(); L'expression -u quivaut u.operator-().
Un Conseil
* Choisir un oprateur global et ami lorsque l'opration est symtrique: + - * / == * Choisir un oprateur membre lorsque l'opration est asymtrique ou ncessite une rfrence : += class Rat { int num, den; public: ... Rat operator-(Rat); //membre : mauvais choix Rat& operator+=(const Rat&); //membre :bon choix friend Rat operator/(Rat , Rat ); //amie : bon choix };
Avec Rat Rat::operator-(Rat b) {return Rat(num*b.den - den* b.num, den*b.den);} Rat& Rat::operator+=(const Rat& d) { num = num*d.den + d.num*den; den = den*d.den; return *this; } Rat operator/(Rat a, Rat b) { return Rat(a.num*b.den, a.den*b.num); } Exemple cout << a << b << a-b << a.operator-(b) << a-1 << a+=2 << a; Rsultat 1/2 2/3 -1/6 -1/6 -1/2 3/2 3/2
Hritage
1. Objectif 2. Classe compose ou classe drive 3. Syntaxe 4. Accs aux donnes et mthodes 5. Classes drives et constructeurs 6. Hritage multiple
Objectif
L'hritage est l'un des principes fondamentaux de la programmation objet. Il a pour objectif de hirarchiser les classes et les objets. L'hritage est mis en oeuvre par la construction de classes drives. Une classe drive * contient les donnes membres de sa classe de base; * peut en ajouter de nouvelles; * possde a priori les mthodes de sa classe de base; * peut redfinir (masquer) certaines mthodes; * peut ajouter de nouvelles mthodes. L'hritage peut tre simple ou multiple.
Avantages:
* Une classe drive modlise un cas particulier de la classe de base, et peut donc utiliser la classe de base; * l'hritage encourage la recherche de la gnralit et de la gnricit; * une hirarchie de classes facilite la solution de problmes complexes; * facilite la maintenance, le dveloppement et les extensions; * peut ajouter de nouvelles mthodes.
Composition ou Hritage
Une classe est compose si certains de ses membres sont eux-mmes des objets. class Carte { class DescrHabitant { DescrHabitant h; protected: int age; string nom; float age; string domicile; }; }; La description d'un habitant fait partie d'une carte d'identit; correct car une carte d'identit n'est pas un cas particulier d'un habitant. class DescrResident : public DescrHabitant{ protected: string residence; }; La description d'un rsident est plus complte que celle d'un habitant: l'information supplmentaire est l'adresse de sa rsidence (qui peut tre diffrente de celle de son domicile).
Syntaxe
La syntaxe pour la dfinition d'une classe drive est class classe_derivee : protection classe_de_base {...}; Les types de protection sont public, protected, private. En gnral, on choisit public.
Des Exemples
* Une voiture comporte quatre (ou cinq) roues, donc class Automobile { Roue roues[5]; ... } * Un segment comporte deux points; * Un anneau est un cas particulier d'un cercle; * Une forme contient un rectangle englobant: class Shape { Rect r; ... } * Un triangle est une forme particulire: class Triangle : public Shape { ... } Discussion : un carr est-il un cas particulier d'un rectangle ?
Implantations
DescrHabitant::DescrHabitant() { cout << "Entrez votre nom : "; cin >> nom; cout << "Entrez votre domicile : "; cin >> domicile; } void DescrHabitant::show() { cout << "Nom: \t\t" << nom << endl; cout << "Domicile \t" << domicile << endl; } DescrResidence::DescrResidence() { // appel implicite du constructeur par dfaut de la classe de base. cout << "Entrez votre residence : "; cin >> residence; } void DescrResidence::show() { DescrHabitant::show(); // l'appel de la mthode de la classe de base. cout << "Residence \t" << residence << endl;
Hritage multiple
Une classe peut hriter de plusieurs classes. Les classes de bases sont alors numres dans la dfinition. class D : public B1, public B2 {...}