Vous êtes sur la page 1sur 41

Ecole Marocaine des Sciences de l’Ingénieur

Marrakech

Classes et objets
Plan du chapitre

▪ Les structures de données (rappel)


▪ Les structures avancées en C++
▪ La notion de classe et d'objet
▪ Les droits d'accès
▪ Constructeur / Destructeur
▪ Les membres données statiques

2
Les structures de données (rappel)
▪ Une structure rassemble des variables, qui peuvent être de types différents, sous un
seul nom
▪ ce qui permet de les manipuler facilement. Elle permet de simplifier l'écriture d'un
programme en regroupant des données liées entre elles.
▪ Exemple

struct point La déclaration précédente définit un type structure nommé point (on dit aussi un
{
modèle de structure nommé point ou parfois, par abus de langage, la structure
int x ;
int y ; point). Quant à x et y, on dit que ce sont des champs ou des membres de la
} structure point.

En C++, nous allons pouvoir, dans une structure, associer aux données constituées par ses membres des méthodes
qu'on nommera "fonctions membres".

3
Les structures avancées en C++
▪ Déclaration d'une structure comportant des fonctions membres
▪ Supposons que nous souhaitions associer à la structure point précédente trois fonctions
▪ initialise pour attribuer des valeurs aux "coordonnées" d'un point
▪ deplace pour modifier les coordonnées d'un point
▪ affiche pour afficher un point : ici, nous nous contenterons, par souci de simplicité, d'afficher les
coordonnées du point
▪ Voici comment nous pourrions déclarer notre structure point :

struct point
{
Déclarations des données membres
int x ;
int y ;

void initialise(int , int);


void deplace(int , int);
Déclaration des fonctions membres (méthodes)
void affiche();
4
}
Les structures avancées en C++
▪ Définir des fonctions membres d'une structure
▪ La définition d'une fonction membre peut se faire de deux manière

Au sein de la structure En dehors de la structure

5
Les structures avancées en C++
▪ Définir des fonctions membres d'une structure
▪ Au sein de la structure
▪ Les fonctions membres sont définis d'une façon classique

▪ Exemple

struct point
{
int x ;
int y ;

void initialise(int a , int b){ Définition de la méthode initialise au sein de la


x=a; structure point
y=b;
};
void deplace(int , int);
void affiche();
} 6
Les structures avancées en C++
▪ Définir des fonctions membres d'une structure
▪ En dehors de la structure
▪ Syntaxe
type_de_retour Nom_de_la_structure :: nom_de_la_fonction (arguments){
//liste des instructions
}

▪ Exemple
void point :: affiche(){
cout << "les coordonnées de votre point sont : " << endl;
cout << " x = " << x << " y = " << y;
}

Le symbole :: correspond à ce que l’on nomme l’opérateur de « résolution de portée », lequel sert à modifier la portée
d’un identificateur. Ici, il signifie que l’identificateur "affiche" concerné est celui défini dans point.

7
Les structures avancées en C++
▪ Utilisation d’une structure avec des méthodes membres

▪ Disposant du type point tel qu’il vient d’être déclaré précédemment, nous pouvons déclarer autant
de variables structurées de ce type que nous le souhaitons.
▪ Par exemple : point a, b ;
▪ déclare deux variables structurées nommées a et b, chacune possédant des membres x et y et
disposant des trois méthodes initialise, deplace et affiche
▪ L’accès aux membres x et y de nos variables structurées a et b pourrait se dérouler comme nous
avons appris à le faire avec les structures usuelles ; ainsi pourrions-nous écrire : a.x = 5 ; a.y=10;
▪ On procède de la même façon pour l'appel d'une fonction membre. Ainsi : a.initialise(5,2) ;

8
Les structures avancées en C++
▪ Exemple récapitulatif

main()
#include <iostream> { point a, b ;
using namespace std ; a.initialise (5, 2) ; a.affiche () ;
/* ------------ Déclaration du type point ------------- */ a.deplace (-2, 4) ; a.affiche () ;
struct point b.initialise (1,-1) ; b.affiche () ;
{ /* déclaration "classique" des données */ }
int x ;
int y ;
/* déclaration des fonctions membres (méthodes) */
void initialise (int, int) ;
void deplace (int, int) ; Résultat :
void affiche ()
{ cout << "Je suis en " << x << " " << y << "\n" ;
}
};
/* ----- Définition des fonctions membres du type point ---- */
void point::initialise (int abs, int ord)
{ x = abs ; y = ord ;
}
void point::deplace (int dx, int dy)
9
{ x += dx ; y += dy ;
}
Les droits d'accées
▪ Exemple
struct Montre{
int heure, minute, seconde;

void set_heure(int, int, int);


Soit la structure suivante : };
void Montre::set_heure(int h, int m, int s){
if( h<=23 && h>=0 && m<=59 && m>=0 && s<=59 && s>=0 ){
heure = h; minute = m; seconde = s;
}
}
main(){
Montre swatch;

swatch.set_heure(2,12,19);

swatch.heure=100; swatch.minute=30; swatch.seconde=900;


}

10
Les droits d'accées

▪ Les divers membres d'une structure sont accessibles en n'importe quel endroit du programme. Une
opération telle que celle-ci est donc faisable : swatch.h = 32;

▪ L'heure d’une montre peut donc être modifié sans passer par la méthode set_heure qui pourrait
vérifier que l'on n'affecte pas une heure supérieur à 24.

▪ Il est possible d'empêcher l'accès à certains attributs et méthodes d’une structure. Cette opération
s'appelle l'encapsulation.

11
Les droits d'accées

▪ Il existe trois modes définissant les droits d’accès aux membres (données et méthodes) d’une
classe :

▪ public
Les méthodes et (plus rarement) les données qui sont déclarées publics sont accessibles par
toutes les méthodes de la classes ainsi que les autres fonctions non membres de la classe.
▪ private
Les méthodes et les données d’une structure qui sont déclarés comme étant privés ne sont
accessibles que par les méthodes membres de la structure, et en aucun par les fonctions
extérieures à cette classe.
▪ protected
Les méthodes et les données d’une classe qui sont déclarés comme étant protégés ne sont
accessibles que par les méthodes membres des classes dérivées ( notion héritage).

12
Les droits d'accées
struct Montre{
private :
Prenant l'exemple précèdent :
int heure, minute, seconde;

public :
void set_heure(int, int, int);
};
• Maintenant on ne peut plus faire un appel void Montre::set_heure(int h, int m, int s){
direct aux données d'une structure . if( h>23 && h<0 && m>59 && m<0 && s>59 && s<0 ){
heure = h; minute = m; seconde = s;
• Un appel genre swatch.heure=30 génère }
une erreur de compilation }
main(){
• On doit donc passer par la méthode Montre swatch;
set_heure()
swatch.set_heure(2,12,19);
• Généralement on met toujours la partie
donnée en privé swatch.heure=100; swatch.minute=30; swatch.seconde=900;
}

13
Notion de classe

▪ La déclaration d'une classe est voisine de celle d'une structure. En effet, il suffit :
▪ de remplacer le mot clé struct par le mot clé class
▪ de préciser quels sont les membres publics (fonctions ou données) et les membres privés en
utilisant les mots clés public et private.

struct point class point


{ {
private : int x ; • Les donnée membres sont par défaut :
int x ; int y ; • Public dans une structure
int y ; • Privées dans les classes
public : public :
void initialise(int , int ); void initialise(int , int ); • Les méthodes membres sont par défaut public
void deplace(int , int); void deplace(int , int); dans les structures
void affiche(); void affiche();
} }

14
Notion d'objet

▪ Comme on a vu la création d'un classe entame la création d'un nouveau type de donnée.

point p1, p2;

▪ Dans la terminologie objet on dit que :

p1 et p2 sont des objets


p1 et p2 sont des instances de la classe point

15
Ecriture du codage sur 3 fichiers
▪ Pour la classe point, on veut définir

1. point.h qui contient la définition de la classe point


2. point.cpp qui contient la définition des méthodes
3. main.cpp qui contient la partie test

16
point.h point.cpp main.cpp
#include<iostream> #include "point.cpp"
class point{
#include "point.h"
private:
using namespace std;
int x;
void point::initialise(int a,int b){x=a;y=b;} main(){
int y;
void point::deplace(int u,int v){x+=u;y+=v;} point p,q ;
public:
void point::affiche(){cout<<"x="<<" "<<x<<" "<<"y="<<y<<endl;}
void initialise(int,int); p.initialise (5, 2) ; p.affiche () ;
p.deplace (-2, 4) ; p.affiche () ;
void deplace(int,int);
q.initialise (1,-1) ; q.affiche () ;
void affiche(); }
};

17
Exercices

1 Créer une classe "Calculatrice" qui a comme méthodes les quartes opérations classiques et deux réels

Créer une classe " Rectangle" qui a comme méthode "calcul_perimetre" et "calcul_surface" et "initialise" et
2 comme données membres longueur et largeur

18
{
cout << "1er nombre: " << endl;
cin >> nombreA ;
cout << "second nombre: " << endl;
cin >> nombreB ;
float soustraction = nombreA - nombreB;
cout << " " << nombreA << " - " << "" << nombreB << "= "<< soustraction <<"\
n";
}

void calculatrice::multiplication() {
cout << "1er nombre: " << endl;
cin >> nombreA ;
cout << "second nombre: " << endl;
cin >> nombreB ;
float multiplication = nombreA * nombreB;
cout << " " << nombreA << "* " << "" << nombreB << "= "<< multiplication <<"\
n";
}

void calculatrice::division() {
cout << "1er nombre: " << endl;
cin >> nombreA ;
cout << "second nombre: " << endl;
cin >> nombreB ;
float division = nombreA / nombreB;
cout << " " << nombreA << "/ " << "" << nombreB << "= "<< division <<"\n";}

void calculatrice::sortie(){
exit(1);
}

// fonction boucle() qui permet le choix d'une des fonctions membres


void boucle(){
//l'objet calcul est crée en statique
calculatrice calcul;
//initialisation de characteres qui permettent le choix
char A; char b = 'm'; char c = 'a'; char d = 'd'; char s = 's'; char o='o';
cout << "Addition(a) ou multiplication(m) ou soustraction(s) ou division(d) ou 19
sortie(o)? " ;
cin >> A ;
#include <iostream>
using namespace std;
class Rectangle{
private:
float L,l;
public:
void initialise(int lon, int lar){
L = lon;
l = lar;
}
float surface(){
return L * l;
}
float perimetre(){
return (L + l)*2;
}
};
int main(){
Rectangle r1, r2;
r1.initialise(10, 9);
r2.initialise(8, 6);
cout<<"Surface de r1="<<" "<<r1.surface()<<endl;
cout<<"perimetre de r1="<<" "<<r1.perimetre()<<endl;
cout<<"Surface de r2="<<" "<<r2.surface()<<endl;
cout<<"perimetre de r2="<<" "<<r1.perimetre()<<endl;
20
}
if (y == 0) {
cout << "Division par zéro non autorisée.\n";
} else {
cout << x << " / " << y << " = " << (x / y) << "\n";
}
}

void sortie() {
exit(1);
}
};

int main() {
char choix;
Calculatrice calcul;

while (true) {
cout << "Choisissez une operation (a - Addition, s - Soustraction, m - Multiplication, d - Division, o - Sortie): ";
cin >> choix;

switch (choix) {
case 'a':
calcul.addition();
break;
case 's':
calcul.soustraction();
break;
case 'm':
calcul.multiplication();
break;
case 'd':
calcul.division();
break;
case 'o':
calcul.sortie();
break;
default:
cout << "Choix invalide. Réessayez.\n";
break;
}
}

return 0;
}

21
Constructeur / destructeur

▪ Pour l'instant, nous avons défini et implémenté pas mal de méthodes. On a


encore 2 méthodes particulières que l'on retrouve dans la plupart des classes : le
constructeur et le destructeur.

22
Constructeur / destructeur
▪ Le constructeur

▪ Comme son nom l'indique, c'est une méthode qui sert à construire l'objet. Dès qu'on
crée un objet, le constructeur est automatiquement appelé.

▪ Exemple

point p1, p2;

le constructeur de l'objet p1 est appelé automatiquement, ainsi que celui de


l'objet p2

23
Constructeur / destructeur
▪ Le rôle du constructeur

▪ Si le constructeur est appelé lors de la création de l'objet, ce n'est pas pour faire joli. En
fait, le rôle principal du constructeur est d'initialiser les attributs.

• Un constructeur par défaut est automatiquement créé par le compilateur. C'est un constructeur vide,
qui ne fait rien de particulier.

On a cependant très souvent besoin de créer soi-même un constructeur qui remplace ce


constructeur vide par défaut.

24
Constructeur / destructeur
▪ Créer un constructeur
▪ Le constructeur est une méthode mais une méthode un peu particulière. En effet, pour
créer un constructeur, il y a deux règles à respecter :
▪ Il faut que la méthode ait le même nom que la classe. Dans notre cas, la méthode devra donc
s'appeler « point».
▪ La méthode ne doit rien renvoyer, pas même void ! C'est une méthode sans aucun type de
retour.
▪ Syntaxe  Exemple

nom_de_classe(liste_des_paramètres){ point(int a, intb){


//traitement X = a; y=b;
} }

25
Constructeur / destructeur
▪ Créer un constructeur
▪ Exemple de la classe point

Comme chaque méthode de classe on peut définir


class point le constructeur en interne ou en externe de la
{ classe
/* déclaration des membres privés */
int x ;
int y ;
/* déclaration des membres publics */
public :
point (int, int) ; // constructeur au lieu d'initialise()
À partir du moment où une classe possède un
void deplace (int, int) ;
constructeur, il n’est plus possible de créer un
void affiche () ;
objet sans fournir les arguments requis par son
};
constructeur (sauf si ce dernier ne possède aucun
point::point(int a, int b){ x=a; y=b; }
argument !).

26
Constructeur / destructeur
▪ Surcharger le constructeur

▪ Comme pour n'importe quelle fonction membre, il est possible de surcharger les
constructeurs, c'est-à-dire définir plusieurs constructeurs avec un nombre/type
d'arguments différents. Ainsi, il sera possible d'initialiser différemment un même objet,
selon la méthode de construction utilisée.

27
Constructeur / destructeur
▪ Le destructeur

▪ C'est une méthode appelée automatiquement lorsqu'un objet est détruit, par exemple à
la fin de la fonction dans laquelle il a été déclaré ou, si l'objet a été alloué
dynamiquement avec new, lors d'un delete.

28
Constructeur / destructeur
▪ Création d'un destructeur

▪ Un destructeur est une méthode qui commence par un tilde (~) suivi du nom de la classe.
▪ Un destructeur ne renvoie aucune valeur, pas même void (comme le constructeur).
▪ Et, nouveauté : le destructeur ne peut prendre aucun paramètre. Il y a donc toujours un seul
destructeur, il ne peut pas être surchargé.

29
Constructeur / destructeur
▪ Création d'un destructeur
▪ Exemple
#include<iostream>
using namespace std;

class Etudiant{
float *note;

public :
Etudiant(int nbrNote){
note = new float[nbrNote]; //le constructeur à allouer la mémoire
cout << "Creation de etudiant avec le nombre de note est " << nbrNote << endl;
}
void moyenne(int nbrNote){
float S=0;
cout<<"saisir les notes"<<endl;
for(int i=0;i<nbrNote;i++)
cin>>note[i];
cout<<"Affichage de la moyenne"<<endl;
for(int i=0;i<nbrNote;i++)
S+=note[i];
float moy=(float)S/nbrNote;
cout<<"moyenne="<<moy<<endl;
}
~Etudiant(){
delete note;
cout << "Destruction de etudiant";
}
};
int main(){
Etudiant e1(4);
e1.moyenne(4);
}
30
Les données membres statiques
▪ Lorsqu’on crée différents objets d’une même classe, chaque objet possède ces
propres données membres.
▪ Exemple

Une déclaration telle que : point p1, p2 ;


calss point provoquera :
{
int x ;
int y ;
……………….
……………….
…………………..
};

31
Les données membres statiques
▪ Pour pouvoir partager des données entre objets de la même classe, on les
déclare statiques.
▪ Exemple
Une déclaration telle que : point p1, p2 ;
provoquera :
class point
{
static int x ;
int y ;
p1.x est identique a p2.x mais p1.y ≠
………………….
p2.y.
…………………
……………..
};

32
Les données membres statiques
▪ Exemple 2 (création d'une classe qui contient le nombre d'instance)

class point
{
int x ;
int y ;
Static int nbrInstance; //compteur d'instance
public:
point(int a, int b){
x = a; y=b;
nbrInstance ++;
}
~point(){
nbrInstance --;
}
};

33
Les données membres statiques
▪ Initialisation des membres données statiques
▪ Une donnée membre statique doit être initialisé explicitement à l'extérieur de la classe
▪ Syntaxe

type_variable nom_de_classe : : nom_variable_statique = valeur;

▪ Exemple

int point::nbrInstance = 0;

▪ L’accès aux données membre statique se réalise en préfixant l’attribut soit par le nom
d’une instance de la classe soit par le nom de la classe elle même.

34
Données membres static
▪ Si un champ membre d'une classe, est déclaré static, il est partagé par toutes
les instances (objets) de la classe.
▪ IL appartient donc à la classe, et non pas aux objets de cette classe.
▪ Il est donc commun à tous les objets de la classe

35
Données membres static
▪ static (dans le cas de la classe) signifie que la variable n'existe qu'en un seul
exemplaire, elle est globale à la classe (variable globale à la classe) Autrement,
chaque objet du type de la classe dispose de sa propre copie.

36
Données et fonction membres static

▪ Une fonction membre déclarée static a la particularité de pouvoir être appelée sans
devoir instancier la classe.

▪ Elle ne peut utiliser que des variables et des fonctions membres static elles aussi, c'est-à-
dire qui ont une existence en dehors de toute instance.

37
Données et fonctions membres static
class A
{
public:
// variable et fonction non statiques
int var1;
void f1() {};
// variable et fonction statiques
static int var2;
static void f2() {};
};
// IMPORTANT : il faut définir la variable static
int A::var2 = 0;

int main()
{
A a; // instance de A
// var1 et f1 nécessitent une instance de A
a.var1 = 1;
a.f1();
// var2 et f2 sont static et n'ont pas besoin d'instance
A::var2 = 1;
A::f2();
}
38
#include <iostream>
#include <stdlib.h>
using namespace std;
class point{
private:
int x,y;

public:
static int x0,y0; // origine du repère commune à tous les points
point(int a,int b){
x=a;
y=b;
}

inline int lire_x() { return x + x0; }


inline int lire_y() { return y + y0; }
};

int point::x0 = 1; // initialisation des données static de la classe


int point::y0 = 0;

int main(){
point a(2,2);

point b(1,3);

cout << a.lire_x() << " et " << a.lire_y() << endl; // résultat 3 et 2
cout << b.lire_x() << " et " << b.lire_y() << endl; // résultat 2 et 3

39
Une méthode statique travaille sur les champs static

#include <iostream>
#include <stdlib.h>
using namespace std;
class Entier
{
static int i;
public:
static int fonc(void);
};

int Entier::i=3;

int Entier::fonc(void)
{
return i;
}

int main(void)
{
// Appelle la fonction statique fonc :
int resultat=Entier::fonc();
cout<<resultat;
return 0;
}

40
Une méthode statique n’utilise pas les données membres non static

class Entier
{
int i;
static int j;
public:
static int fonc(void);
};

int Entier::j=0;

int Entier::fonc(void)
{
j=1; // Légal.
return i; // ERREUR ! fonc ne peut pas accéder à i.
}

41

Vous aimerez peut-être aussi