Cours C/C++ les classes, tutoriel & guide de travaux pratiques en pdf.
Un exemple : la classe Point
Nous allons commencer par un court exemple destiné à illustrer pratiquement l’utilisation d’une classe. Il s’agit ici de définir le type Point, défini par ses coordonnées cartésiennes ou polaires.
Définition et implémentation
Une classe ayant une représentation interne de niveau private et un ensemble de fonctions membres de niveau public est par définition un type de données abstrait (abstract data type). Ainsi, la classe Point, dont le seul but est de définir le type de données Point, ou coordonnée dans un plan, pourrait se définir comme suit :
/*************************************** File : Point.h Author : /users/pro/mjn (Markus Jaton) Date : 05.07.1995 Location : telec2.einev.ch Mail : jaton@einev.ch ****************************************/
// Inclusion de fichiers librairie standards
typedef boolean int; #include <iostream.h>
class Point { private :
// Ces données sont inaccessibles pour l’application. double x, y; public : Point() ; // constructeur par defaut // Constructeur d’assignation, // ou d’affectation Point(double xx, double yy); // constructeur de copie Point(const Point& coord); // Destructeur (ne fait rien) ~Point() {;} // Coordonnées polaires Point(double module, long angleInMilliDegrees); // Opérateur de test d’égalité boolean operator==(const Point& cx) const; // Opérateur d’assignation void operator=(const Point& cx); // Fonction permettant l’impression // sur un ostream. void print(ostream &os); };
est un type de données abstrait. L’application peut l’utiliser sans connaître aucun des détails d’implémentation. Un passage à un système de coordonnées polaires peut s’effectuer sans que l’application ne soit touchée. Essayons d’analyser d’un peu plus près cette définition de classe très simple, pour parvenir à comprendre les règles de base de définition d’une classe.
La définition commence par le mot réservé private, suivi de la déclaration de deux valeurs de type double. Ceci est la représentation interne de la classe. On représente la classe Point par ses coordonnées cartésiennes, représentées par des nombres en virgule flottante de double précision. On pourrait également la représenter par son module et son argument: l’application n’a en principe pas à s’occuper de ceci. D’ailleurs, toute tentative de la part d’une application, d’adresser le membre x de la variable z, elle-même de type Point, par exemple, générerait de la part du compilateur l’erreur suivante :
myProg.C, line XXX : error : Cannot access z.x : private member //HPC++
Suit une partie précédée par le mot reservé public. C’est ici que commence l’interface de la classe pour les utilisateurs. En principe, les utilisateurs normaux de la classe ne voyent que cette partie. Cette partie liste les opérations qu’un utilisateur peut demander à un objet de la classe Point. En jargon OO, on dira que cette partie spécifie les messages auxquels peut répondre un objet de type Point.
La déclaration que nous avons donnée çi-dessus représente l’interface de la classe. Cet interface est (du point de vue de sa signification) équivalent à un module de définition en MODULA-2, ou à une spécification en ADA. Cet interface est habituellement stocké dans un fichier séparé, un header file (fichier en-tête). Le fichier en-tête ne contient pas de code1, mais uniquement des définitions, ainsi que le veut le bon usage en C et en C++.
Le code est contenu dans un fichier séparé, le fichier implémentation (implementation file). Cette convention correspond exactement à la convention en langage C traditionnel, pour définir les librairies externes. La définition de classes au moyen de C++ par l’intermédiaire de fichiers en-tête est néanmoins plus puissante que l’utilisation habituelle de fichiers en-tête en C, parceque les concepts utilisés par le langage permettent une plus grande abstraction que la simple définition de prototypes de fonction.
Concentrons-nous maintenant sur l’implémentation de cette classe Point. Nous allons tout d’abord la donner telle quelle, sans explications préalables de la syntaxe, et nous reviendrons ensuite progressivement sur les divers éléments de cette implémentation.