5. CLASSES ET OBJETS

La classe est une généralisation de la notion de type utilisateur, dans lequel données (membres données) et méthodes (fonctions membres) sont associées. En POO pure, les données sont encapsulées et ne peuvent être accédées que par les méthodes. Le C++ autorise à n’encapsuler qu’une partie des données d’une classe. Il existe même un type particulier, qui est la généralisation de la structure du C, dans lequel données et mé-thodes sont effectivement associées, mais sans aucune encapsulation. Sur le plan conceptuel, il correspond à un cas particulier de la classe : une classe dans laquelle aucune donnée n’est encapsulée. Comme une classe n’est qu’un type utilisateur, les objets possèdent les mêmes caractéristiques que les variables ordinaires, en particulier en ce qui concerne leurs différentes classes d’allocation (statique, automatique, dynamique).

5-1. Structures en C++

En C, une déclaration telle que :
struct point
{
int x ;
int y ;
} ;

définit un type structure nommé point, x et y étant des champs ou membres de la structure point. On peut déclarer des variables que l’on utilisera ensuite comme en C:
struct point a, b ; // réserve l’emplacement pour deux structures nommées a et b, de type point
En C++, on peut associer des méthodes aux données d’une structure. Cependant, une telle association est relativement artificielle et son principal intérêt est de préparer à la notion de classe.

Déclaration d’une structure comportant des fonctions membres

Supposons que nous souhaitons 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 d’afficher les coordonnées du point.
Voici comment l’on pourrait déclarer la structure point :

Déclaration du type point

struct point
{ /* 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) ;
void affiche () ; } ;
Outre la déclaration classique des données, apparaissent les déclarations des fonctions membres. La défini-tion de ces fonctions sera réalisée un peu plus loin. Il est prévu que la méthode initialise, par exemple, rece-vra deux arguments de type int sans préciser leur rôle. Il ne faut pourtant pas oublier que l’en-tête de initia-lise vise à affecter aux membres x et y les valeurs reçues en arguments.

Définition des fonctions membres

C’est pratiquement la définition classique de fonctions. Ainsi, la définition de initialise serait:
void point::initialise (int abs, int ord)
{
x = abs ;
y = ord ;
}
Le symbole :: correspond à l’opérateur de résolution de portée, servant à modifier la portée d’un identifi-cateur. Ici, il signifie que l’identificateur initialise concerné est celui défini dans point.
/* ------------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)
{
x += dx; y += dy;
}
void point::affiche ()
{
cout <<“Je suis en ” << x <<“ ” << y << “\n” ;
}

Utilisation d’une structure comportant des fonctions membres

Disposant du type point, on peut déclarer autant de structures de ce type que l’on veut. Par exemple,
point a, b ;
déclare deux structures a et b possédant, chacune, des membres x et y et disposant des trois méthodes initia-lise, deplace et affiche. Remarquons que si chaque structure dispose de ses propres membres données, il n’en va pas de même des fonctions membres, générées qu’une seule fois. L’accès aux membres x et y des struc-tures a et b pourrait se dérouler comme en C, et l’on pourrait écrire :
a.x = 5 ;
accédant ainsi directement aux données en violant le principe d’encapsulation, ce qui serait bien accepté à ce niveau de structure de C++. On procéderait de la même manière pour appeler une fonction membre:
a.initialise (5,2) ; // appel la fonction membre initialise de la structure a, en lui transmettant 5 et 2 en arguments.

5-2. Notion de classe

Une classe est une structure où seulement certains membres et/ou fonctions sont publics, les autres étant dits privés. 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 les membres publics et les membres privés en utilisant les mots clé public et private.

En faisant de la structure point une classe dans laquelle les membres données sont privés et les fonctions membres publiques, sa déclaration serait la suivante :

Déclaration de la classe point

class point
{ /* déclaration des membres privés */
private : /* facultatif */
int x ;
int y ;
/* déclaration des membres publics */
public :
void initialise (int, int) ;
void deplace (int, int) ;
void affiche () ;
} ;

La définition des fonctions membres d’une classe se fait comme celles d’une structure. Ces fonctions ont accès à l’ensemble des membres de la classe et l’utilisation d’une classe est identique à celle d’une structure.

5-3. Affectation d'obejts

En C, on peut affecter à une structure la valeur d’une autre structure de même type. Voir cet exemple :
struct point
{
int x ;
int y ;
} ;
struct point a, b ;
….
a = b ; // ou encore : a.x = b.x ; a.y = b.y ;
En C++, cette possibilité d’affectation globale s’étend aux objets de même type. Elle correspond à une reco-pie des valeurs des membres données, que ceux-ci soient publics ou non. Voir cet exemple: class point
{
int x ;
public :
int y ;
…..
} ;
point a, b ;
….
b = a ; // mais ici, il n’est plus possible d’écrire : b.x = a.x ; b.y = a.y ;

En effet, si la deuxième affectation est légale (y étant ici public), la première ne l’est pas, car x est privé. L’affectation b = a est toujours légale, quelque soit le statut des membres donnés. On peut considérer qu’elle ne viole pas le principe d’encapsulation, les données privées de b restant toujours inaccessibles directement.