>C++ 2< |
PROGRAMMATION ORIENTE OBJET: NOTION DE CLASSE
I- INTRODUCTION
On attend dun programme informatique
- lexactitude (réponse aux spécifications)
- la robustesse (réaction correcte à une utilisation " hors
normes ")
- lextensibilité (aptitude à lévolution)
- la réutilisabilité (utilisation de modules)
- la portabilité (support dune autre implémentation)
- lefficience (performance en termes de vitesse dexécution et de consommation
mémoire)
Les langages évolués de type C ou PASCAL, reposent sur le principe de la programmation
structurée (algorithmes + structures de données)
Le C++ et un langage orienté objet. Un langage orienté objet permet la manipulation de
classes. Comme on le verra dans ce chapitre, la classe généralise la notion de
structure.
Une classe contient des variables (ou " données ") et des fonctions
(ou " méthodes ") permettant de manipuler ces variables.
Les langages " orientés objet " ont été développés pour faciliter
lécriture et améliorer la qualité des logiciels en termes de modularité.
Un langage orienté objet sera livré avec une bibliothèque de classes. Le développeur
utilise ces classes pour mettre au point ses logiciels.
Rappel sur la notion de prototype de fonction:
En C++, comme en C, on a fréquemment besoin de déclarer des prototypes de fonctions.
Par exemple, dans les fichiers den-tête (de type *.h), sont déclarés les
prototypes des fonctions appelées par le programme.
Le prototype dune fonction est constitué du nom de la fonction, du type de la
valeur de retour, du type des arguments à passer
Exemples: void ma_fonction1()
void ma_fonction2(int n, float u) // prototype "complet"
void ma_fonction2(int, float) // prototype "réduit"
int ma_fonction3(char *x) // prototype "complet"
int ma_fonction3(char *) // prototype "réduit"
int ma_fonction4(int &u) // prototype "complet"
int ma_fonction4(int &) // prototype "réduit"
On utilise indifféremment, dans les fichiers den-tête, le prototype complet ou le
prototype réduit.
II- NOTION DE CLASSE
Exemple (à tester) et exercice II-1 :
(il faut ajuster la temporisation aux performances de la machine utilisée)
#include <iostream.h> // les classes
#include <conio.h>
class point
{
int x,y;
public: void initialise(int,int);
void deplace(int,int);
void affiche();
};
void point::initialise(int abs,int ord)
{x = abs; y = ord;}
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void main()
{
point a,b;
a.initialise(1,4);
a.affiche();
tempo(10);
a.deplace(17,10);
a.affiche();
b = a; // affectation autorisee
tempo(15);
clrscr();
b.affiche();
getch() ;}
"point" est une classe. Cette classe est constituée des données x et y et des
fonctions membres (ou méthodes) " initialise ",
" deplace ", " affiche ". On déclare la classe en
début de programme (données et prototype des fonctions membres), puis on définit le
contenu des fonctions membres.
Les données x et y sont dites privées. Ceci signifie que lon ne peut les manipuler
quau travers des fonctions membres. On dit que le langage C++ réalise
lencapsulation des données.
a et b sont des objets de classe "point", cest-à-dire des variables de
type "point".
On a défini ici un nouveau type de variable, propre à cet application, comme on le fait
en C avec les structures.
Suivant le principe dit de " lencapsulation des données ", la
notation a.x est interdite.
Exercice II-2:
Utiliser la classe " point " précédente. Ecrire une fonction de
prototype void test() dans laquelle on déclare un point u, on linitialise, on
laffiche , on le déplace et on laffiche à nouveau. Le programme principal
main ne contient que lappel à test.
Exercice II-3:
Ecrire une fonction de prototype void test(point &u) (référence) similaire. Ne pas
déclarer de point local dans test. Déclarer un point local a dans le programme principal
main et appeler la fonction test en passant le paramètre a.
Exercice II-4:
Ecrire une fonction de prototype point test() qui retourne un point. Ce point sera
initialisé et affiché dans test puis déplacé et à nouveau affiché dans main.
III- NOTION DE CONSTRUCTEUR
Un constructeur est une fonction membre systématiquement exécutée lors de la
déclaration dun objet statique, automatique, ou dynamique.
On ne traitera dans ce qui suit que des objets automatiques.
Dans lexemple de la classe point, le constructeur remplace la fonction membre
initialise.
Exemple (à tester) et exercice II-5:
#include <iostream.h> // constructeur
#include <conio.h>
class point
{
int x,y;
public: point(); // noter le type du constructeur (pas de "void")
void deplace(int,int);
void affiche();
};
point::point() // initialisation par default
{x = 20; y = 10;} // grace au constructeur
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void main()
{
point a,b; // les deux points sont initialisés en 20,10
a.affiche();
tempo(10);
a.deplace(17,10);
a.affiche();
tempo(15);
clrscr();
b.affiche();
getch() ;}
Exemple (à tester) et exercice II-6:
#include <iostream.h> // constructeur
#include <conio.h>
class point
{
int x,y;
public: point(int,int); // noter le type du constructeur (pas de "void")
void deplace(int,int);
void affiche();
};
point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;} // grace au constructeur, ici paramètres à passer
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void main()
{
point a(20,10),b(30,20); // les deux points sont initialises:a en 20,10 b en 30,20
a.affiche();
tempo(10);
a.deplace(17,10);
a.affiche();
tempo(15);
clrscr();
b.affiche();
getch() ;}
Exercice II-7: Reprendre lexercice II-2, en utilisant la classe de lexercice
II-6
Exercice II-8: Reprendre lexercice II-3, en utilisant la classe de lexercice
II-6
Exercice II-9: Reprendre lexercice II-4, en utilisant la classe de lexercice
II-6
IV- NOTION DE DESTRUCTEUR
Le destructeur est une fonction membre systématiquement exécutée "à la fin de la
vie " dun objet statique, automatique, ou dynamique.
On ne peut pas passer de paramètres par le destructeur.
On ne traitera dans ce qui suit que des objets automatiques.
Exemple (à tester) et exercice II-10:
#include <iostream.h> // destructeur
#include <conio.h>
class point
{
int x,y;
public: point(int,int);
void deplace(int,int);
void affiche();
~point(); // noter le type du destructeur
};
point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;} // grace au constructeur, ici paramètres à passer
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
point::~point()
{cout<<"Frapper une touche...";getch();
cout<<"destruction du point x ="<<x<<"
y="<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void test()
{
point u(3,7);
u.affiche();
tempo(20);
}
void main()
{point a(1,4);a.affiche();tempo(20);
test();
point b(5,10);b.affiche();
getch() ;}
V- ALLOCATION DYNAMIQUE
Lorsque les membres données dune classe sont des pointeurs, le constructeur est
utilisé pour lallocation dynamique de mémoire sur ce pointeur.
Le destructeur est utilisé pour libérer la place.
Exemple (à tester) et exercice II-11:
#include <iostream.h> // Allocation dynamique de données membres
#include <stdlib.h>
#include <conio.h>
class calcul
{int nbval,*val;
public: calcul(int,int); // constructeur
~calcul(); // destructeur
void affiche();
};
calcul::calcul(int nb,int mul) //constructeur
{int i;
nbval = nb;
val = new int[nbval]; // reserve de la place
for(i=0;i<nbval;i++)val[i] = i*mul;
}
calcul::~calcul()
{delete val;} // abandon de la place reservee
void calcul::affiche()
{int i;
for(i=0;i<nbval;i++)cout<<val[i]<<" ";
cout<<"\n";
}
void main()
{
clrscr();
calcul suite1(10,4);
suite1.affiche();
calcul suite2(6,8);
suite2.affiche();
getch() ;}
VI- EXERCICES RECAPITULATIFS
Exemple (à tester) et exercice II-12:
Cet exemple ne fonctionne quen environnement DOS. Il utilise les fonctions
graphiques classiques du TURBO C. On crée une classe " losange ", les
fonctions membres permettent de manipuler ce losange.
#include <graphics.h>
#include <conio.h>
#include <iostream.h>
#include <dos.h>
class losange
{
int x,y,dx,dy,couleur;
public:
losange();
void deplace(int,int,int);
void affiche();
void efface();
};
losange::losange() // constructeur
{x=100;y=100;dx=60;dy=100;couleur=BLUE;}
void losange::deplace(int depx,int depy,int coul)
{x=x+depx;y=y+depy;couleur=coul;}
void losange::affiche()
{int tab[10];
tab[0]=x;tab[1]=y;tab[2]=x+dx/2;tab[3]=y+dy/2;
tab[4]=x;tab[5]=y+dy;tab[6]=x-dx/2;tab[7]=y+dy/2;
tab[8]=x;tab[9]=y;
setfillstyle(SOLID_FILL,couleur);
fillpoly(5,tab);
}
void losange::efface()
{int tab[10];
tab[0]=x;tab[1]=y;tab[2]=x+dx/2;tab[3]=y+dy/2;
tab[4]=x;tab[5]=y+dy;tab[6]=x-dx/2;tab[7]=y+dy/2;
tab[8]=x;tab[9]=y;
setcolor(getbkcolor()); // pour effacer le contour
setfillstyle(SOLID_FILL,getbkcolor());
fillpoly(5,tab);
}
void init_graph()
{
int gd,gm;
detectgraph(&gd,&gm);
initgraph(&gd,&gm,"c:\\cplus\\bgi");
setbkcolor(YELLOW);
}
void main()
{
losange l;
init_graph();
l.affiche();
getch();closegraph();
}
Exercice II- 13: Modifier le programme principal de sorte de faire clignoter le losange
tant que lutilisateur na pas appuyé sur une touche.
Exercice II- 14: Modifier le programme principal de sorte de déplacer le losange
dune position à une autre position, tant que lutilisateur na pas
appuyé sur une touche.
VII- CORRIGE DES EXERCICES
Exercice II-2:
#include <iostream.h> // les classes
#include <conio.h>
class point
{
int x,y;
public: void initialise(int,int);
void deplace(int,int);
void affiche();
};
void point::initialise(int abs,int ord)
{x = abs; y = ord;}
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void test()
{
point u;
u.initialise(1,4);u.affiche();
tempo(10);
u.deplace(17,10);u.affiche();
}
void main()
{test();getch() ;}
Exercice II-3:
#include <iostream.h> // les classes
#include <conio.h>
class point
{
int x,y;
public: void initialise(int,int);
void deplace(int,int);
void affiche();
};
void point::initialise(int abs,int ord)
{x = abs; y = ord;}
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void test(point &u)
{
u.initialise(1,4);u.affiche();
tempo(10);
u.deplace(17,10);u.affiche();
}
void main()
{point a;test(a);getch() ;}
Exercice II-4:
#include <iostream.h> // les classes
#include <conio.h>
class point
{
int x,y;
public: void initialise(int,int);
void deplace(int,int);
void affiche();
};
void point::initialise(int abs,int ord)
{x = abs; y = ord;}
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
point test()
{point u;
u.initialise(1,4);u.affiche();return u;}
void main()
{point a;
a = test();
tempo(10);
a.deplace(17,10);a.affiche();getch() ;}
Exercice II-7:
#include <iostream.h>
#include <conio.h>
class point
{
int x,y;
public: point(int,int); // noter le type du constructeur (pas de "void")
void deplace(int,int);
void affiche();
};
point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;} // grace au constructeur, ici paramètres à passer
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void test()
{
point u(1,4);
u.affiche();
tempo(10);
u.deplace(17,10);
u.affiche();
}
void main()
{test();getch() ;}
Exercice II-8:
#include <iostream.h> // les classes
#include <conio.h>
class point
{
int x,y;
public: point(int,int); // noter le type du constructeur (pas de "void")
void deplace(int,int);
void affiche();
};
point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;} // grace au constructeur, ici paramètres à passer
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
void test(point &u)
{
u.affiche();
tempo(10);
u.deplace(17,10);u.affiche();
}
void main()
{point a(1,4);test(a);getch() ;}
Exercice II-9:
#include <iostream.h> // les classes
#include <conio.h>
class point
{
int x,y;
public: point(int,int); // noter le type du constructeur (pas de "void")
void deplace(int,int);
void affiche();
};
point::point(int abs,int ord) // initialisation par default
{x = abs; y = ord;} // grace au constructeur, ici paramètres à passer
void point::deplace(int dx,int dy)
{x = x+dx; y = y+dy;}
void point::affiche()
{gotoxy(x,y);cout<<"Je suis en "<<x<<"
"<<y<<"\n";}
void tempo(int duree)
{float stop ;stop = duree*10000.0;for(;stop>0;stop=stop-1.0);}
point test()
{point u(5,6);
u.affiche();return u;}
void main()
{point a(1,4);
a.affiche();
tempo(15);
a = test();
tempo(10);
a.deplace(17,10);a.affiche();}
Exercice II-13:
void main()
{
losange l;
init_graph();
while(!kbhit())
{
l.affiche(); delay(500);
l.efface(); delay(500);
}
getch();closegraph();
}
Exercice II-14:
void main()
{
losange l;
init_graph();
while(!kbhit())
{
l.affiche(); delay(500);l.efface();
l.deplace(150,150,RED);
l.affiche();delay(500);l.efface();
l.deplace(-150,-150,BLUE);
}
getch();closegraph();
}