Professional Documents
Culture Documents
Exemples
par Claude DELANNOY
Ingnieur de lENSEM (cole nationale suprieure dlectricit
et de mcanique) de Nancy
Ingnieur informaticien au CNRS (Centre national de la recherche scientifique)
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 066 1
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 066 2 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
Aprs laffectation, on aboutit : Voici ce que pourrait tre la dfinition de notre classe (les points
dlicats sont comments au sein mme des instructions).
1
5
e1 8
3 Dfinition de la classe set_int
100 4 #include "setint.h"
5 #include <iostream>
using namespace std ;
1 /*************** constructeur ********************/
100 5 set_int::set_int (int dim)
5 8 { adval = new int [nmax = dim] ; // allocation tableau
e2 3 // de valeurs
4 nelem = 0 ;
}
/****************** destructeur ******************/
Il reste rgler le cas o e1 et e2 correspondent au mme objet.
set_int::~set_int ()
Or, la surdfinition de loprateur daffectation peut se faire indif- { delete adval ; // libration tableau
fremment avec lun des deux en-ttes suivants : // de valeurs
operator = (set_int & e) }
operator = (set_int e) /********** constructeur par recopie *************/
set_int::set_int (set_int & e)
Si la transmission de e1 loprateur daffectation a lieu par { adval = new int [nmax = e.nmax] ;// allocation nouveau tableau
valeur et si le constructeur par recopie a t redfini de faon appro- nelem = e.nelem ;
prie (par cration dun nouvel emplacement dynamique), lalgo- int i ;
rithme propos fonctionnera sans problme. for (i=0 ; i<nelem ; i++)// copie ancien tableau dans nouveau
En revanche, si la transmission de e1 a lieu par rfrence, on abor- adval[i] = e.adval[i] ;
dera lalgorithme avec cette situation : }
/************ oprateur d'affectation ************/
set_int & set_int::operator = (set_int & e) // commentaires faits
1 // pour b = a
5 { if (this != &e) // on ne fait rien pour a = a
8 { delete adval ; // libration partie dynamique de b
100
3 adval = new int [nmax = e.nmax] ; // allocation nouvel
5
4 // ensemble pour a
e1 et e2
nelem = e.nelem ; // dans lequel on recopie
int i ; // entirement l'ensemble b
Lemplacement dynamique associ b (donc aussi a) sera libr for (i=0 ; i<nelem ; i++) // avec sa partie dynamique
avant que lon tente de lutiliser pour le recopier dans un nouvel adval[i] = e.adval[i] ;
emplacement. La situation sera alors catastrophique. }
Enfin, il faut dcider de la valeur de retour fournie par loprateur. return * this ;
ce niveau, tout dpend de l'usage que nous souhaitons en faire : }
si nous nous contentons d'affectations simples (e2 = e1), nous /************ fonction membre cardinal ***********/
n'avons besoin d'aucune valeur de retour (void) ; int set_int::cardinal ()
en revanche, si nous souhaitons pouvoir traiter une affectation { return nelem ;
multiple ou, plus gnralement, faire en sorte que (comme on peut s'y }
/************ oprateur d'ajout << ***************/
attendre !) l'expression e2 = e1 ait une valeur (probablement celle de
set_int & set_int::operator << (int nb)
e2 !), il est ncessaire que loprateur fournisse une valeur de retour.
{ // on examine si nb appartient dj l'ensemble
Nous choisirons ici la seconde possibilit qui a le mrite dtre // en utilisant l'oprateur %
plus gnrale. // s'il n'y appartient pas, et s'il y a encore de la place
Voici la dclaration dfinitive de notre classe set_int (suppose // on l'ajoute l'ensemble
place ici dans un fichier nomm setint.h) : if ( ! (nb % *this) && nelem < nmax ) adval [nelem++] = nb ;
return (*this) ;
}
Dclaration de la classe set_in /*********** oprateur d'appartenance % **********/
/* fichier SETINT.H : dclaration de la classe set_int */ int operator % (int nb, set_int & e)
#include <iostream> { int i=0 ;
using namespace std ; // on examine si nb appartient dj l'ensemble
class set_int
{ int * adval ; // adresse du tableau // (dans ce cas i vaudra nele en fin de boucle)
// des valeurs while ( (i<e.nelem) && (e.adval[i] != nb) ) i++ ;
int nmax ; // nombre maxi d'lments return (i<e.nelem) ;
int nelem ; // nombre courant d'lments }
public :
set_int (int = 20) ; // constructeur /****** oprateur << pour sortie sur un flot *****/
set_int (set_int &) ; // constructeur par recopie ostream & operator << (ostream & sortie, set_int & e)
set_int & operator = (set_int &) ; // oprateur d'affectation { sortie << "[ " ;
~set_int () ; // destructeur int i ;
int cardinal () ; // cardinal de l'ensemble
set_int & operator << (int) ; // ajout d'un lment for (i=0 ; i<e.nelem ; i++)
friend int operator % (int, set_int &) ; sortie << e.adval[i] << " " ;
// appartenance d'un lment sortie << "]" ;
// envoi ensemble dans un flot return sortie ;
friend ostream & operator << (ostream &, set_int &) ;
}; }
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 066 3
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 066 4 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 066 5
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
D'o une premire bauche de la classe liste : moins pratique car il faudrait obligatoirement agir sur le pointeur de
liste avant de savoir si l'on est la fin).
struct element // structure d'un lment de liste
{ element * suivant ; // pointeur sur l'lment suivant En dfinitive, nous introduisons trois nouvelles fonctions mem-
mere * contenu ; // pointeur sur un objet quelconque bres :
};
class liste void * premier () ;
{ element * debut ; // pointeur sur premier lment void * prochain () ;
public : int fini () ;
liste () ; // constructeur
~liste () ; // destructeur Comme dans le premier exemple, il nous faut nous proccuper
void ajoute (mere *) ; // ajoute un lment en dbut de liste des problmes daffectation et de copie dobjets de type liste. Ici,
void affiche () ; nous nous contenterons dinterdire ces oprations lutilisateur en
..... levant une exception lorsque lune dentre elles sera tente. Pour ce
}; faire, nous crons (un peu artificiellement) deux classes exc_affec et
exc_copie (en fait vides). Pour faciliter la gestion des exceptions cor-
Pour mettre en uvre le parcours de la liste, nous prvoyons des respondantes, nous les faisons toutes deux driver dune troisime
fonctions lmentaires pour : nomme exc_liste.
initialiser le parcours ; Voici la liste complte des diffrentes classes voulues. Notez
avancer d'un lment. quici, nous avons regroup dclaration et dfinition de classes. De
Celles-ci ncessitent un pointeur sur un lment courant . Il plus, au sein des dclarations, nous avons exploit la possibilit
sera membre donne de notre classe liste ; nous le nommerons cou- quoffre C++ de dfinir directement certaines fonctions que lon qua-
rant. Par ailleurs, les deux fonctions membres voques doivent lifie alors de fonctions en ligne . Cette faon de procder simplifie
fournir en retour une information concernant l'objet courant. ce les dfinitions courtes. En outre, elle offre au compilateur la possibi-
niveau, on peut choisir entre : lit (pas lobligation) dintroduire le code objet correspondant cha-
ladresse de l'lment courant ; que appel, en vitant les changements de contexte qui seraient
ladresse de l'objet courant (cest--dire lobjet point par ll- induits par un appel classique (sauvegarde de registres, conserva-
ment courant) ; tion dune adresse de retour...).
la valeur de l'lment courant. Enfin, nous avons ralis un petit programme dessai de la classe
La deuxime solution semble la plus naturelle. Il faut simplement liste, en dfinissant deux classes point et complexe (lesquelles nont
fournir lutilisateur un moyen de dtecter la fin de liste. Nous pr- pas besoin de driver lune de lautre), drives de la classe abs-
voirons donc une fonction supplmentaire permettant de savoir si la traite mere et dotes chacune dune fonction affiche approprie.
fin de liste est atteinte (en toute rigueur, nous aurions aussi pu four- Nous y avons tent une affectation entre objets de type liste et nous
nir un pointeur nul comme adresse de l'objet courant ; mais ce serait interceptons convenablement lexception exc_liste.
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 066 6 Techniques de lIngnieur, trait Informatique industrielle