Vous êtes sur la page 1sur 15

INTRODUCTION AUX CLASSES

1. Notions de base sur les classes et les objets

1.1. Forme générale d’une classe

Une classe est un type défini par l’utilisateur. Une classe se déclare à l’aide du mot clé class
et regroupe des données membres et des fonctions membres (ou méthodes) agissant sur ces
données membres.

class Nom-de-la-classe
{
private :
Données et fonctions membres privées
Protected :
Données et fonctions membres protégées
public :
Données et fonction publiques
};

Définitions :

 objet : Un objet est une instance d’une classe, c’est à dire un emplacement mémoire
adressable dont le type est celui de la classe

 fonction membre (ou méthode) : un membre d'une classe qui est une fonction ; les

fonctions membres définissent le comportement des classes

 donnée membre : un membre qui est une variable

 encapsulation des données : L'association de données et fonctions au sein d'une

classe, avec la possibilité de rendre privés certains d'entre eux. Encapsuler n'est pas

cacher mais interdire.

Accessibilité des membres d’une classe


Les différents membres d’une classe peuvent être à accès protégé (protected), privé
(private) ou public (public) :
 private

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 1


les membres privés ne peuvent être utilisés (modifiés pour les données, appelés pour les
méthodes) que par les méthodes de la classe elle-même et à partir des classes amies
 protected
les membres protégés ne peuvent être utilisés que par les méthodes de la classe et des
classes dérivées ainsi des classes amies
 public
les membres publics peuvent être utilisés et modifiés par tous et partout où ils sont visibles

Les variables sont le plus souvent private ou protected, tandis que les méthodes sont
usuellement public.
Par défaut, tous les membres d’une classe ont l’accessibilité private

class A
{
private :
-------

protected : Interdit
-------

public :
-------

};

A objA

Figure 1. : L’effet des accessibilités sur les fonctions membres et les objets d’une classe

Les fonctions membres d’une classe peuvent accéder aux membres publics protégés et

privés.

Les objets d’une classe ne peuvent accéder qu’aux membres publics de la classe.

Graphiquement, selon la notation UML une classe peut se présenter comme il suit :

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 2


donné Nom-de-la-classe
Données membres

Fonctions membres

Figure 2. : Représentation graphique d’une classe selon la notation UML

1.2. Création d’objets

Exemple :

// declaration d'objets de la classe Etudiant


Etudiant a, b, c;
//Determiner la taille en octets de la classe
int size=sizeof (Etudiant) :

Allocation dynamique

On peut créer dynamiquement des instances de classe en faisant appel au (à un des)


constructeur(s) de la classe. L’opérateur new() permet d’allouer dynamiquement l’espace
mémoire nécessaire pour une (ou plusieurs) instance(s) de classe donnée, de la même
manière que pour les types standard :

Etudiant* pe=new Etudiant; // pour un seul exemplaire


Etudiant* pe=new Etudiant[10]; //pour un tableau de 10 étudiants.

La désallocation se fait par l’opérateur delete ou delete[]

Accès aux membres

Soit e une instance de classe Etudiant déclarée par :


Etudiant e;

 L’opérateur "."
L’opérateur "." permet un accès direct aux attributs ou méthodes de l’instance :

cout <<e.nom; //accès à l’attribut nom


e.calculNoteFinale(); //exécution de la méthode calculNoteFinale()

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 3


 L’opérateur "-"

L’opérateur "-" permet l’accès aux attributs ou méthodes de l’instance via un


pointeur

Par exemple, si pe est un pointeur sur Etudiant,


Etudiant* pe = &e;

alors on accède aux membres xxx de e par pe - xxx :


cout <<pe - nom;
pe - calculNoteFinale();

1.3. Exemple de définition d’une classe

Ex :

#include <iostream>
using namespace std;
class Boite
{
public:
double longueur;
double largeur;
double hauteur;
double volume()//fonction par défaut inline
{return longueur*largeur*hauteur ;}
} ;

int main()
{
Boite b1 ;// b1 est un objet ou instance de la classe Boite
b1.longueur= 78.0;

b1.largeur= 24.0;
b1.hauteur=18.0 ;
double volb1 =0.0 ;
volb1 = b1.volume() ;
cout << endl
<< "Volume de la boite b1 :" << volb1 << endl ;
return 0 ;
}

1.4. Définition séparée de fonction et l’opérateur de résolution de portée

Les fonctions définies à l'intérieur d'une classe sont implicitement qualifiées « en ligne »
(inline). Conséquence : la plupart des fonctions membres seront définies séparément. Seules
les fonctions courtes, rapides et fréquemment appelées mériteront d'être définies dans la

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 4


classe. Définir les fonctions membres à l'extérieur de la classe allège la définition de cette
dernière et la rend plus compacte. On utilise alors l’opérateur de résolution de portée.

Ex :
#include <iostream>
using namespace std;
class Boite
{

public:
double longueur;
double largeur;
double hauteur;

double volume() ;
} ;

int main()
{
Boite b1 ;
b1.longueur= 78.0;
b1.largeur= 24.0;
b1.hauteur=18.0 ;
double volb1 =0.0 ;
volb1 = b1.volume() ;
cout << endl
<< "Volume de la boite b1 :" << volb1 << endl ;
return 0 ;
}

double Boite::volume() //utilisation de l’opérateur de résolution de portée


{ return longueur*largeur*hauteur ;}

2. Constructeurs et destructeurs

2.1. Constructeurs

Un constructeur d'une classe est une fonction membre spéciale qui :


 a le même nom que la classe,
 n'indique pas de type de retour
Le rôle d'un constructeur est d'initialiser un objet, notamment en donnant des valeurs à ses
données membres.
Un constructeur de la classe est toujours appelé, explicitement ou implicitement, lorsqu'un
objet de cette classe est créé, et en particulier chaque fois qu'une variable ayant cette classe
pour type est définie.

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 5


Une classe peut posséder plusieurs constructeurs, qui doivent alors avoir des signatures
différentes.
Comme les autres fonctions membres, les constructeurs peuvent être déclarés dans la classe
ou définis ailleurs.

Ex :

#include <iostream>
using namespace std;
class Boite
{
public:
double longueur;
double largeur;
double hauteur;
Boite(double lg, double lr, double ht)
{
longueur = lg ;
largeur = lr ;
hauteur = ht ;
}

double volume()
{ return longueur*largeur*hauteur ;}
} ;

int main()
{
Boite b1(78.0,24.0,18.0);//Boite b1=Boite(78.0,24.0,18.0);
Boite b2(8.0, 5.0, 1.0) ;
double volb =0.0 ;
volb = b1.volume() ;
cout << endl ;
cout<< "Volume de la boite b1 :" << volb << endl ;
return 0 ;
}

Constructeur par défaut :

Le constructeur par défaut est un constructeur qui peut être appelé sans paramètres : ou bien
il n'en a pas, ou bien tous ses paramètres ont des valeurs par défaut.

Paramètres par défaut d’un constructeur

Boite(double lg = 1.0, double lr = 1.0, double ht = 1.0)

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 6


longueur = lg ;

largeur = lr ;

hauteur = ht ;

Liste d’initialisation des paramètres d’un constructeur

Ex :

Boite(double lg =1.0, double lr = 1.0, double ht = 1.0) : longueur(lg),


largeur(lr), hauteur(ht)

{

}

2.2. Destructeurs

Un destructeur est une fonction membre spéciale. Il a le même nom que la classe, précédé du

caractère ~. Il n'a pas de paramètre, ni de type de retour. Il y a donc au plus un destructeur

par classe. Le destructeur d'une classe est appelé lorsqu'un objet de la classe est détruit.

Les objets qui sont les valeurs de variables globales sont détruits immédiatement après la

terminaison de la fonction principale (en principe main), dans l'ordre inverse de la déclaration

des variables globales.

Les objets qui ont été alloués dynamiquement ne sont détruits que lors d'un appel de delete

les concernant.

Ex :

~Boite()
{
Instructions du destructeur
}

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 7


3. Fonctions et classes amies

3.1. Fonctions amies

Une fonction amie d'une classe est une fonction qui, sans être membre de cette classe, a le

droit d'accéder à tous ses membres, aussi bien publics que privés.

Une fonction amie doit être déclarée ou définie dans la classe qui accorde le droit d'accès,

précédée du mot réservé friend.

Ex :

// fonctions amies
#include <iostream>
using namespace std;
class Beta; // nécessaire ici pour la déclaration de la
//function amie
class Alpha
{
private:
int data;
public:
Alpha(): data(3)
{ }
friend int frdfunc(Alpha, Beta); // function amie
};

class Beta
{
private:
int data
public:
Beta(): data(7)
{ }
friend int frdfunc(Alpha, Beta);
};

int frdfunc(Alpha a, Beta b)


{ return (a.data+b.data);}

int main()
{
Alpha aa;
Beta bb;
cout <<frdfunc(aa,bb) << endl;
return 0;
}

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 8


Remarque: On déclare une fonction amie avec le mot-clé friend. Cette déclaration peut être
placée dans n’importe quelle section (private, public, protected) de la classe.

3.2. Classes amies

Toutes les fonctions membres d’une classe peuvent devenir fonctions amies si la classe elle-

même est amie. Une classe amie d'une classe C est une classe qui a le droit d'accéder à tous

les membres de C. Une telle classe doit être déclarée dans la classe C (la classe qui accorde

le droit d'accès), précédée du mot réservé friend, indifféremment parmi les membres privés ou

parmi les membres publics de C.

Ex :

//classes amies
#include <iostream>
using namespace std;
class Alpha
{
private:
int data;
public:
Alpha(): data(3)
{ }
// void afficherBeta(Beta b)
//{cout<<b.data;}
friend class Beta; // Beta comme classe amie de Alpha
};
class Beta
{
public:
void func1(Alpha a)
{cout << "\ndata=" << a.data;}
void func2(Alpha a)
{cout << "n\data=" << a.data;}
};

int main()
{
Alpha unAlpha;
Beta unBeta;
//unAlpha.afficherBata(unBeta) ;
unBeta.func1(unAlpha);
unBeta.func2(unAlpha);
cout << endl;
return 0;
}

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 9


Remarque: On déclare une classe amie avec le mot-clé friend.

4. Modèle de classe (classe template)


Un modèle de classe est un type paramétré, par d'autres types et par des valeurs connues
lors de la compilation. On obtient l'instanciation d'un modèle de classe en créant des objets.
Ici, contrairement à ce qui se passe pour les fonctions, les arguments du modèle doivent être
toujours explicités.

Exemple introductif

class Stack
{
private :
int st[MAX] ;// tableau d’entiers
int top ;//l’indice du sommet du tas
public :
Stack() ;//constructeur
void push(int var) ;
int pop() ;
} ;

Si nous voulions stocker des types long nous serions obligés de définir une nouvelle classe :

class LongStack
{
private :
long st[MAX] ;
int top ;
public :
LongStack() ;
void push(long var) ;
long pop() ;
} ;

Ex : classe template avec fonction membre définie à l’intérieur de la classe

#include <iostream>
using namespace std ;
const int MAX = 100;
template <class Type>
class Stack
{
private:
Type st[MAX];
int top;
public:
Stack()
{top = -1;}

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 10


void push(Type var)
{st[++top] = var;}

Type pop()
{return st[top--];}
};

int main()
{
Stack<float> s1; // s1 est un objet de la classe Stack<float>
s1.push(1111.1F) ;
s1.push(2222.2F) ;
s1.push(3333.3f) ;
cout << "1 : "<< s1.pop() <<endl;
cout << "2 : "<< s1.pop() <<endl;
cout << "3 : "<< s1.pop() <<endl;

Stack <long> s2;


s2.push(123123123L);
s2.push(234234234L);
s2.push(345345345L);
cout << "1: " << s2.pop() << endl;
cout << "2: " << s2.pop() << endl;
cout << "3: " << s2.pop() << endl;

return 0;
}

Ex : classe template avec fonction membre définie à l’extérieur de la classe

#include <iostream>
using namespace std ;
const int MAX = 100;
template <class Type>
class Stack
{
private:
Type st[MAX];
int top;
public:
Stack();
void push(Type var);
Type pop();
};

template<class Type>
Stack<Type>::Stack()
{top = -1;}

template<class Type>
void Stack<Type>::push(Type var)
{st[++top]= var;}

template<class Type>
Type Stack<Type>:: pop()

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 11


{return st[top--];}

int main()
{
Stack<float> s1; // s1 est un objet de la classe Stack<float>
s1.push(1111.1F) ;
s1.push(2222.2F) ;
S1.push(3333.3f) ;
cout << "1 : "<< s1.pop() <<endl;
cout << "2 : " << s1.pop() <<endl;
cout << "3 : " << s1.pop() <<endl;

Stack <long> s2;


S2.push(123123123L);
S2.push(234234234L);
S2.push(345345345L);
cout << "1: " << s2.pop() << endl;
cout << "2: " << s2.pop() << endl;
cout << "3: " << s2.pop() << endl;

return 0;
}

5. Pointeurs sur les objets

Les pointeurs peuvent pointer sur des objets de la même manière qu’ils pointent
sur les variables.
Dans les situations ou on ne sait pas d’avance combien d’objets seront créés on
peut utiliser le mot clé new pour créer des objets pendant l’exécution du
programme. L’utilisation de new permet de retourner un pointeur sur un objet sans
nom.

Ex :

#include <iostream>
using namespace std;
class Distance
{
private:
int m;
double cm;
public:
void getDistance()
{
cout<<"\n Entrer les metres: ";
cin>>m ;
cout<< " Entrer les centimetres : " ;
cin>>cm ;
}

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 12


void afficherDistance()
{cout<< m << ‘m’ << cm << "cm" ;}

} ;

int main()
{
Distance dist ;
dist.getDistance() ;
dist.afficherDistance() ;

Distance* distptr ; // pointeur sur Distance


distptr = new Distance ;
distptr -> getDistance() ;
distptr -> afficherDistance() ;
cout << endl ;
return 0 ;
};

Exemple : liste chaînée unidirectionnelle

#include <iostream>
using namespace std ;
class Element
{
public:
int donnee;
Element* suivant;
};

class ListeChainee
{
private:
Element* premier;
public:
ListeChainee()
{premier = NULL;}
void ajouterElement(int d);
void afficherLesElements() ;
} ;

void ListeChainee ::ajouterElement(int d)


{
Element* nouveau = new Element ;

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 13


nouveau -> donnee = d ;
nouveau -> suivant = premier ;
premier = nouveau ;
}
void ListeChainee :: afficherLesElements()
{
Element* courant = premier
while(courant != NULL)
{
cout << courant -> donnee <<endl ;
courant = courant -> suivant ;
}
}

int main()
{
ListeChainee lc ;
lc.ajouterElement(25) ;
lc.ajouterElement(36) ;
lc.ajouterElement(49) ;
lc.ajouterElement(64) ;

lc.afficherLesElements() ;
return 0 ;
}

EXERCICE DE PROGRAMMATION
I) Construire une classe appelée Tableau. Les données membres seront
constituées par les éléments de type entier d’un tableau à une dimension.
a. Définir les méthodes comme ci-après :
- afficherDonne() pour afficher les données du tableau
- altererDonne() pour altérer les éléments du tableau
- triTableau() pour faire le tri du tableau
- sommeElement() pour retourner la somme des éléments du tableau
- plusPetitElement() pour retourner le plus petit élément du tableau
- plusGrandElement() pour retourner le plus grand élément du tableau
b. Tester la classe ainsi construite dans la méthode principale main()

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 14


NB : Il revient au programmeur de spécifier selon le cas le type de retour et la liste
des paramètres

II) Considérer l’exercice précédent avec une classe générique (template) capable de
prendre un tableau de type quelconque.

Th. K. DAGBA, ENEAM/UAC décembre 2020 Page 15

Vous aimerez peut-être aussi