Professional Documents
Culture Documents
Concepts
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 065 1
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 2 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
classe) qui sont autorises (par une classe) accder aux donnes namespace une_bibli
(encapsules) de la classe ; { // dclarations usuelles
la surdfinition doprateurs permet de doter une classe
}
doprations analogues celles que lon rencontre pour les types
prdfinis. Par exemple, on pourra dfinir une classe nomme Pour se rfrer des identificateurs dfinis dans cet espace de
complexe (destine reprsenter des nombres complexes) et la noms, on utilisera une instruction using :
munir des oprations daddition, de soustraction, de multiplication using namespace une_bibli
et de division. Qui plus est, ces oprations pourront utiliser les sym- // ici, les identificateurs de une_bibli sont connus
boles existants : +, -, *, / ;
les entres-sorties deviennent fondes sur la notion de flot , On peut aussi utiliser l'instruction using pour faire un choix per-
ce qui permet de leur donner un sens pour les types dfinis par luti- manent :
lisateur que sont les classes (grce au mcanisme de surdfinition using une_bibli::point ; // dornavant, l'identificateur point,
doprateur) ; // employ seul correspondra celui
la notion de patron permet de dfinir des modles utilisables // dfini dans l'espace de noms une_bibli
pour gnrer diffrentes classes ou diffrentes fonctions qualifies
parfois de gnriques, mme si cette gnricit nest pas totalement Tous les identificateurs des fichiers en-tte standards sont dfinis
intgre dans le langage lui-mme, comme cest par exemple le cas dans lespace de noms std ; aussi est-il ncessaire de recourir syst-
avec ADA ; matiquement linstruction :
dans la bibliothque standard de C++, qui vient complter using namespace std ; // utilisation des fichiers
celle du C, toujours disponible, on trouve de nombreux patrons de // en-tte standard //
classes et de fonctions permettant de mettre en uvre les structures
de donnes et les algorithmes les plus usuels, vitant ainsi davoir Gnralement, cette instruction figurera un niveau global. Elle
rinventer la roue la moindre occasion. ne peut cependant apparatre que si lespace de noms quelle men-
tionne existe dj ; en pratique, cela signifie que cette instruction
sera place aprs linclusion des fichiers en-tte.
2. Amliorations de C++
par rapport C 2.3 Nouvelles possibilits
d'entres-sorties
Nous dcrivons ici les principales amliorations non orientes
objet que C++ a apport au langage C. C++ dispose de nouvelles facilits d'entres-sorties. Bien qu'elles
soient fortement lies des aspects POO (surdfinition d'oprateur
en particulier), elles sont parfaitement utilisables en dehors de ce
2.1 Scurisation de lutilisation contexte. C'est tout particulirement le cas des possibilits
des fonctions d'entres-sorties conversationnelles (clavier, cran) qui remplacent
avantageusement les fonctions printf et scanf. Ainsi :
Le langage C est laxiste en matire de dclaration de fonctions. En cout << expression_1 << expression_2 << ......... << expression_n
effet, sil permet deffectuer des dclarations compltes (prototype affiche sur le flot cout (connect par dfaut la sortie standard
avec type des arguments et de la valeur de retour), il autorise gale- stdout) les valeurs des diffrentes expressions indiques, suivant
ment des dclarations partielles, voire mme dans certains cas une une prsentation adapte leur type. De mme :
absence totale de dclaration.
C++ ne conserve que laspect le plus fiable de C, tel quil tait dj cin >> variable_1 >> variable_2 >> ......... >> variable_n
utilis par les programmeurs C soucieux de scuriser leurs pro- lit sur le flot cin (connect par dfaut l'entre standard stdin) des
grammes. Il impose que toute fonction utilise dans un fichier informations de l'un des types char, short, int, long, float, double ou
source fasse lobjet : char * (les pointeurs ne sont pas admis). Les conventions d'analyse
soit d'une dclaration sous forme d'un prototype (il prcise des caractres lus sont comparables celles de scanf, avec cette
la fois le nom de la fonction, le type de ses arguments ventuels et principale diffrence que la lecture d'un caractre commence par
le type de sa valeur de retour), comme dans cet exemple : sauter les espaces blancs (espace, tabulation horizontale, tabulation
float fexp (int, double, char *) ; verticale, fin de ligne, changement de page).
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 065 3
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
En C++, vous pouvez en outre utiliser des commentaires de fin Exemple : utilisation de la transmission d'arguments par rf-
de ligne en introduisant les deux caractres : //. Dans ce cas, tout rence en C++
ce qui est situ entre // et la fin de la ligne est un commentaire. Notez
que cette nouvelle possibilit n'apporte qu'un surcrot de confort et #include <iostream>
de scurit ; en effet, une ligne telle que : using namespace std ;
main()
cout << "bonjour\n" ; // formule de politesse { void echange (int &, int &) ;
peut toujours tre crite ainsi : int n=10, p=20 ;
cout << "avant appel : " << n << " " << p << "\n" ;
cout << "bonjour\n" ; /*formule de politesse*/
echange (n, p) ; // attention, ici pas de &n, &p
Vous pouvez mler (volontairement ou non !) les deux formules. cout << "apres appel : " << n << " " << p << "\n" ;
Dans ce cas, notez que, dans : }
/* partie1 // partie2 */ partie3 void echange (int & a, int & b)
{ int c ;
le commentaire ouvert par /* ne se termine qu'au prochain */ ; cout << "debut echange : " << a << " " << b << "\n" ;
donc partie1 et partie2 sont des commentaires, tandis que partie3 c=a;a=b;b=c;
est considr comme appartenant aux instructions. De mme, dans : cout << "fin echange : " << a << " " << b << "\n" ;
partie1 // partie2 /* partie3 */ partie4 }
le commentaire introduit par // stend jusqu la fin de la ligne. Il ________________________________
concerne donc partie2, partie3 et partie4.
avant appel : 10 20
dbut echange : 10 20
fin echange : 20 10
2.5 Transmission par rfrence aprs appel : 20 10
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 4 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
Il peut galement mettre en place des conversions implicites. membres donnes privs x et y et trois fonctions membres publi-
ques initialise, deplace et affiche :
void sosie (int) ; // sosie I /* ------- Dclaration de la classe point -------- */
void sosie (double) ; // sosie II class point
char c ; float y ; { /* dclaration des membres privs */
..... private :
sosie(c) ; // appelle sosie I, aprs conversion de c en int int x ;
sosie(y) ; // appelle sosie II, aprs conversion de y en double int y ;
/* dclaration des membres publics */
Dune manire gnrale, il existe des rgles trs prcises (trop public :
complexes pour tre cites ici) que le compilateur utilise dans sa void initialise (int, int) ; // initialise les coordonnes
recherche de la bonne fonction. void deplace (int, int) ; // modifie les coordonnes
void affiche () ; // affiche les coordonnes
};
La dfinition d'une classe consiste fournir les dfinitions des
2.8 Gestion dynamique de la mmoire fonctions membre. On indique alors le nom de la classe correspon-
dante, l'aide de l'oprateur de rsolution de porte (::). Au sein de
la dfinition mme, les membres (privs ou publics donnes ou
Comme en C, les emplacement allous aux variables (ou aux fonctions) sont directement accessibles sans qu'il soit ncessaire de
objets) se classent en trois catgories, suivant la faon sont ils sont prciser le nom de la classe. Voici, par exemple, ce que pourrait tre
allous : la dfinition de la fonction initialise de la classe prcdente.
automatique : les emplacements sont allous lentre dans void point::initialise (int abs, int ord)
une fonction, et librs sa sortie ; il en va ainsi pour les arguments { x = abs ; y = ord ;
dune fonction et pour les variables locales ; }
statique : les emplacements sont allous une fois pour toute void point::deplace (int dx, int dy)
avant le dbut de lexcution ; { x = x + dx ; y = y + dy ;
dynamique : les emplacements sont allous lors de lexcu- }
tion, sur demande explicite du programme ; il en va de mme pour void point::affiche ()
leur libration. { cout << "Je suis en " << x << " " << y << "\n" ;
}
Mais, alors que la gestion dynamique en C recourait aux fonctions
malloc et calloc, il est conseill en C++ dutiliser les oprateurs new Ici, x et y reprsentent implicitement les membres x et y d'un
et delete. Plus prcisment, si T reprsente un type quelconque objet de la classe point.
(ventuellement classe), avec :
T * ad ;
ad = new T ;
3.2 Utilisation d'une classe
on alloue lemplacement ncessaire pour un emplacement de type On dclare un objet d'un type classe donn en faisant prc-
T et on affecte ad ladresse correspondante. der son nom de celui de la classe, comme dans l'instruction sui-
Avec : vante qui dclare deux objets a et b de type point :
point a, b ;
delete ad ;
On peut accder n'importe quel membre public (donne ou
on libre lemplacement prcdemment allou. fonction) d'une classe en utilisant l'oprateur . (point). Par exemple :
a.initialise (5, 2) ;
appelle la fonction membre initialise de la classe laquelle appar-
3. Notion de classe tient lobjet a, c'est--dire, ici, la classe point.
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 065 5
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Une fonction membre portant le mme nom que sa classe se Lexemple prcdent tait form dun seul fichier source conte-
nomme un constructeur. Ds qu'une classe comporte un construc- nant la fois la dclaration de la classe, sa dfinition et son utilisa-
teur, il n'est plus possible de dclarer un objet du type corres- tion. En pratique, on aura gnralement intrt placer chaque
pondant, sans fournir des valeurs pour les arguments requis par ce partie dans un fichier source diffrent, de manire permettre dif-
constructeur (sauf si ce dernier ne possde aucun argument). Le frents programmes dutiliser une mme classe.
constructeur est appel aprs l'allocation de l'espace mmoire des- Dans ces conditions, on pourra compiler la dfinition de la classe
tin lobjet (quelle que soit la classe dallocation correspondante - (une fois pour toutes) et fournir tout utilisateur potentiel le module
automatique, dynamique ou statique). objet correspondant accompagn dun fichier en-tte contenant la
Par dfinition, un constructeur ne renvoie pas de valeur (aucune dclaration de la classe.
indication de type, pas mme void, ne doit figurer devant sa dcla-
ration ou sa dfinition).
Une fonction membre portant le mme nom que sa classe, pr- 3.7 Membres donnes statiques
cd du symbole tilde (~), se nomme un destructeur. Le destructeur
est appel avant la libration de l'espace mmoire associ l'objet.
Par dfinition, un destructeur ne peut pas comporter d'arguments et Un membre donne dclar avec l'attribut static est partag par
il ne renvoie pas de valeur (aucune indication de type ne doit tre tous les objets de la mme classe. Il existe mme lorsque aucun
prvue). objet de cette classe n'a t dclar. Un membre donne statique
doit tre initialis explicitement, l'extrieur de la classe (mme s'il
est priv), en utilisant l'oprateur de rsolution de porte (::) pour
spcifier sa classe. En gnral, son initialisation se fait dans la dfi-
3.5 Exemple complet nition de la classe.
Voici un exemple complet regroupant la dclaration, la dfinition 3.8 Surdfinition des fonctions membres
et lutilisation dune classe point. Notez que la mthode initialise
prcdente a t avantageusement remplace par un constructeur. et arguments par dfaut
Exemple : dclaration, dfinition et utilisation dune classe Il s'agit simplement de la gnralisation aux fonctions membres
/* -------- Dclaration de la classe point --------- */ des possibilits dj offertes par C++ pour les fonctions
class point ordinaires . Voici par exemple une classe point surdfinissant
{ /* dclaration des membres publics */ trois constructeurs et disposant dune fonction affiche possdant un
public : argument par dfaut.
point (int, int) ; // constructeur
class point
void deplace (int, int) ;
{ public :
void affiche () ;
point () ; // constr 1 (sans argument)
/* dclaration des membres privs */
point (int) ; // constr 2 (un argument)
int x ;
point (int, int) ; // constr 3 (deux arguments)
int y ;
void affiche (char * = "") ; // un argument par dfaut
};
private :
/* --- Dfinition des fonctions membre de la classe point -- */ int x, y ;
point::point (int abs, int ord) };
{ x = abs ; y = ord ; point::point () // constructeur 1
} { x=0;y=0;
void point::deplace (int dx, int dy) }
{ x = x + dx ; y = y + dy ; point::point (int abs) // constructeur 2
} { x = y = abs ;
void point::affiche () }
{ cout << "Je suis en " << x << " " << y << "\n" ; point::point (int abs, int ord) // constructeur 3
} { x = abs ; y = ord ;
}
/* -------- Utilisation de la classe point -------- */ void point::affiche (char * message)
main() { cout << message << "Je suis en : " << x << " " << y << "\n" ;
{ point a(5,2) ; }
a.affiche () ;
a.deplace (-2, 4) ; a.affiche () ; En voici quelques exemples dutilisation.
point b(1,-1) ;
b.affiche () ; point a ; // appel constructeur 1
b=a; point b (5) ; // appel constructeur 2
b.affiche () ; point c (3, 12) ; // appel constructeur 3
} .....
______________________ a.affiche () ;
// affiche : Je suis en : 0 0
Je suis en 5 2 b.affiche ("Point b - ") ;
Je suis en 3 6 // affiche : Point b - Je suis en : 5 5
Je suis en 1 -1 c.affiche ("Hello ---- ") ;
Je suis en 3 6 // affiche : Hello ---- Je suis en : 3 12
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 6 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 065 7
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Mais il existe d'autres situations, plus courantes, qui mettent en Gnralement, la fonction membre fct possdera un argument ou
uvre un tel mcanisme, savoir : une valeur de retour de type A (ce qui justifiera sa dclaration d'ami-
la transmission d'un objet par valeur en argument d'appel ti). Pour compiler sa dclaration (au sein de la dclaration de A), il
d'une fonction ; suffira au compilateur de savoir que A est une classe ; si sa dclara-
la transmission d'un objet par valeur en valeur de retour d'une tion n'est pas connue ce niveau, on pourra se contenter de :
fonction. class A ;
Dans toutes ces situations d'initialisation par recopie, le construc-
teur par recopie employ est : En revanche, pour compiler la dfinition de fct, le compilateur
devra possder les caractristiques de A, donc disposer de sa dcla-
soit un constructeur de la forme type (type &) ou type (const type ration.
&) s'il en existe un ; ce dernier doit alors prendre en charge la recopie
de tous les membres de lobjet, y compris ceux qui sont des objets ; il
peut cependant s'appuyer sur les possibilits de transmission d'infor-
mation entre constructeurs, prsente au paragraphe 3.13 ; 4.3 Toutes les fonctions d'une classe B
soit, dans le cas contraire, ce que l'on nomme un sont amies d'une autre classe A
constructeur de recopie par dfaut , qui recopie les diffrents
membres de l'objet. Si certains de ces membres sont eux-mmes
des objets, la recopie sera ralise par appel de son propre cons- Dans ce cas, plutt que d'utiliser autant de dclarations d'amiti
tructeur par recopie (qui pourra tre soit un constructeur par dfaut, que de fonctions membre, on utilise (dans la dclaration de la classe
soit un constructeur dfini dans la classe correspondante). A) la dclaration (globale) suivante :
friend class B ;
La fonction fct, membre de la classe B, ayant le prototype spcifi, On doit se limiter aux oprateurs existants, en conservant leur
est autorise accder aux membres privs de la classe A. pluralit (unaire, binaire). Les oprateurs ainsi surdfinis gar-
Pour qu'il puisse compiler convenablement la dclaration de A, dent leur priorit et leur associativit habituelle.
donc en particulier la dclaration d'amiti relative fct, le compila- Un oprateur surdfini doit toujours possder un oprande de
teur devra connatre la dclaration de B (mais pas ncessairement type classe (on ne peut donc pas modifier les significations des op-
sa dfinition). rateurs usuels). Il doit donc s'agir :
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 8 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
soit d'une fonction membre, auquel cas elle dispose obligatoi- Le processus peut tre rpt loisir : de B, on peut trs bien dri-
rement d'un argument implicite du type de sa classe (this) ; ver une nouvelle classe C, de C driver une nouvelle classe D, et
soit d'une fonction indpendante (ou plutt amie) possdant ainsi de suite.
au moins un argument de type classe.
Il ne faut pas faire d'hypothse sur la signification a priori d'un
oprateur ; par exemple, la signification de += pour une classe ne 6.1 Redfinition dune fonction membre
peut en aucun cas tre dduite de la signification de + et de = pour
cette mme classe.
La classe drive peut redfinir une fonction membre de la classe
de base en fournissant une fonction membre de mme nom (ses
arguments peuvent tre diffrents en nombre et en type ; sa valeur
5.3 Tableau rcapitulatif de retour peut tre de type diffrent). Cest alors cette dernire qui
sera utilise pour tout objet de la classe drive.
(0) class A
Oprateurs surdfinissables en C++ { void f (int) ;
(classs par priorit dcroissante) .....
}
Pluralit Oprateurs Associativit class B extends A
{ int f (int, float) ;
Binaire () (3) [] (3) -> (2)(3) > .....
}
Unaire + - ++ (5) -- (5) ! ~ * & (1) <
new (4) delete (4) (cast) int n, p ; float x ;
Binaire */% > Aa;Bb;
a.f(n) ; // appelle f de A
Binaire +- > p = b.f(n, x) ; // appelle f de B
Binaire << >> >
Binaire < <= > >= >
Binaire == != >
6.2 Modalits d'accs la classe de base
Binaire & >
Les membres privs d'une classe de base ne sont jamais accessi-
Binaire ^ >
bles aux fonctions membre de sa classe drive.
Binaire || > Outre les statuts public ou priv, il existe un statut protg . Un
Binaire && > membre protg se comporte comme un membre priv pour un uti-
lisateur quelconque de la classe ou de la classe drive, mais
Binaire | > comme un membre public pour la classe drive. Voici un tableau
Binaire = (1)(3) += -= *= /= %= < rcapitulant ces diffrents possibilits :
&= ^ = |= <<= >>= (0)
Binaire , (2) >
(1) S'il n'est pas surdfini, il possde une signification par dfaut.
(2) Depuis la version 2.0 seulement. Drivation publique
(3) Doit tre dfini comme fonction membre.
(4) un niveau global (fonction indpendante) avant la version 2.0.
Depuis la version 2.0, il peut en outre tre surdfini pour une classe ; Accs aux Nouveau
dans ce cas, il doit l'tre comme fonction membre. fonctions Accs statut
Statut
(5) Jusqu' la version 3, on ne peut pas distinguer entre les notations membres un utilisateur dans la classe
dans la classe
pr et post . Depuis la version 3, ces oprateurs (lorsqu'ils sont et amies de la classe drive, en cas
dfinis de faon unaire) correspondent la notation pr ; mais il en de base
de la classe drive de nouvelle
existe une dfinition binaire (avec deuxime oprande fictif de type int) drive drivation
qui correspond la notation post .
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 065 9
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Statut initial Accs FMA Accs Nouveau Accs Nouveau Accs Nouveau Accs
utilisateur statut utilisateur statut utilisateur statut utilisateur
public oui oui public oui protg non priv non
protg oui non protg non protg non priv non
priv oui non priv non priv non priv non
Lorsqu'un membre (donne ou fonction) est redfini dans une B (B & b) : A(b) ; // appel du constructeur par recopie de A
classe drive, il reste toujours possible (soit dans les fonctions // auquel sera transmise la partie de B hrite de A
membre de cette classe, soit pour un client de cette classe) d'acc- // (grce aux rgles de compatibilit entre
der aux membres de mme nom de la classe de base ; il suffit pour // classe drive et classe de base)
cela d'utiliser l'oprateur de rsolution de porte (::), sous rserve,
bien sr, qu'un tel accs soit autoris. d'un constructeur sans argument, si aucun constructeur de la
classe de base n'est mentionn dans l'en-tte ; dans ce cas, il est
ncessaire que la classe de base dispose d'un tel constructeur sans
argument, faute de quoi, on obtiendrait une erreur de compilation.
6.3 Redfinition et surdfinition
Il faut noter quen C++ (contrairement Java), lorsquune fonction 6.6 Consquences de l'hritage
membre est redfinie dans une classe drive, elle masque toutes
les fonctions membres de mme nom de la classe de base (mme Considrons la situation suivante, dans laquelle la classe A pos-
sil y a surdfinition). Autrement dit, la recherche par le compilateur sde une fonction membre f (dont nous ne prcisons pas les argu-
dune fonction de nom donn ne se fait que dans une seule ments) fournissant un rsultat de type t (quelconque : type de base
porte : soit celle de la classe concerne, soit celle dune classe ou type dfini par l'utilisateur, ventuellement type classe) :
de base. On peut dire, en quelque sorte, que la surdfinition ne fran-
chit pas la barrire de lhritage. class A class B : public A
{ ..... { .....
public : };
6.4 Appel des constructeurs t f (...) ;
.....
et des destructeurs };
Aa; // a est du type A
Soit B une classe drive d'une classe de base A. Naturellement,
Bb; // b est du type B, driv de A
ds lors que B possde au moins un constructeur, la cration d'un
objet de type B implique obligatoirement l'appel d'un constructeur Naturellement, un appel tel que a.f(...) a un sens et il fournit un
de B. Mais, de plus, ce constructeur de B doit prvoir des arguments rsultat de type t. Le fait que B hrite publiquement de A permet
destination d'un constructeur de A (une exception a lieu soit si A alors de donner un sens un appel tel que :
n'a pas de constructeur, soit si A possde un constructeur sans
argument). Ces arguments sont prciss dans la dfinition du cons- b.f (...)
tructeur de B, comme dans cet exemple. La fonction f agira sur b, comme s'il tait de type A. Le rsultat
B (int x, int y, char coul) : A (x, y) ; fourni par f sera cependant toujours de type t, mme, notamment,
lorsque le type t est prcisment le type A (le rsultat de f pourra
toutefois tre soumis d'ventuelles conversions s'il est affect
une variable dun type diffrent de t et compatible par affectation).
6.5 Cas particulier du constructeur
par recopie
6.7 Cas particulier de l'oprateur
En plus des rgles dj mentionnes au paragraphe 6.4, il faut d'affectation
ajouter que si la classe drive B ne possde pas de constructeur
par recopie, il y aura appel du constructeur par recopie par dfaut de
Considrons une classe B drivant d'une classe A.
B, lequel procdera ainsi :
Si la classe drive B n'a pas surdfini l'oprateur d'affectation,
appel du constructeur par recopie de A (soit celui qui y a t
l'affectation de deux objets de type B se droule membre membre,
dfini, soit le constructeur par recopie par dfaut) ;
en considrant que la partie hrite de A constitue un membre.
initialisation des membres donnes de B qui ne sont pas hri- Ainsi, les membres propres B sont traits par l'affectation prvue
ts de A. pour leur type (par dfaut ou surdfinie, suivant le cas). La partie
En revanche, un problme se pose lorsque la classe drive dfi- hrite de A est traite par l'affectation prvue dans la classe A.
nit explicitement un constructeur par recopie. En effet, dans ce cas, Si la classe drive B a surdfini l'oprateur =, l'affectation de
il faut tenir compte de ce que l'appel de ce constructeur par recopie deux objets de type B fera ncessairement appel l'oprateur =
entranera l'appel : dfini dans B. Celui de A ne sera pas appel, mme s'il a t surd-
du constructeur de la classe de base mentionn dans son en- fini. Il faudra donc que l'oprateur = de B prenne en charge tout ce
tte, comme dans cet exemple (il s'agit ici d'un constructeur par qui concerne l'affectation d'objets de type B, y compris pour ce qui
recopie de la classe de base, mais il pourrait s'agir de n'importe quel est des membres hrits de A (quitte faire appel l'oprateur
autre constructeur). d'affectation de A).
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 10 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
6.8 Compatibilit entre objets pointcoul (.....) : point (.....), coul (.....)
d'une classe de base et objets | | |
| | |
d'une classe drive
arguments arguments arguments
pointcoul point coul
Considrons :
class A class B : public A
{ ..... { ..... 6.9.3 Classes virtuelles
}; };
Aa; // a est du type A Par le biais de drivations successives, il est tout fait possible
Bb; // b est du type B, driv de A qu'une classe hrite deux fois d'une mme classe.
A * ada ; // ada est un pointeur sur des objets de type A
B * adb ; // adb est un pointeur sur des objets de type B Exemple : dans lequel D hrite deux fois de A.
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 065 11
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 12 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
Le type_de_base peut tre quelconque, pour peu qu'il ne s'agisse 8.4 Association d'un flot un fichier
pas d'un pointeur (char * est cependant accept ; il correspond
l'entre d'une chane de caractres, et non d'une adresse).
Les espaces_blancs (espace, tabulation horizontale \t ou verti- La classe ofstream, drivant de ostream, permet de crer un flot
cale \v, fin de ligne \n et changement de page \f ) servent de de sortie associ un fichier :
dlimiteurs (comme dans scanf ), y compris pour les chanes de ofstream flot (char * nomfich, mode_d_ouverture)
caractres.
Nous en avons un exemple avec le flot prdfini cin, au paragra- Le mode douverture est dfini par un entier dont on positionne
phe 2.3. certains bits en utilisant des constantes prdfinies (que lon peut
combiner par loprateur ||) choisies parmi les suivantes :
(0)
8.2.2 Principales fonctions membres
istream & get (char & c) Diffrents modes d'ouverture d'un fichier
On peut alors envoyer un objet de type T sur un flot quelconque ; Introduite par la version 3, la notion de patron de fonctions per-
par exemple : met de dfinir ce que l'on nomme souvent des fonctions gn-
riques . Plus prcisment, l'aide d'une unique dfinition compor-
T a, b ; // objets de type T
tant des paramtres de type , on dcrit toute une famille de fonc-
.....
tions ; le compilateur fabrique (on dit aussi instancie ) la ou
cout << a << b ;
les fonctions ncessaires la demande (on nomme souvent ces ins-
De mme, on surdfinira >> pour une classe donne T, en utilisant tances fonctions patrons ).
ce canevas :
istream & operator >> (istream & entree, T & objet)
{ 9.1 Dfinition
// Lecture des informations correspondant aux
// diffrents membres de objet en utilisant les
// possibilits classiques de >> pour les types de base On prcise les paramtres (muets) de type, en faisant prcder
// c'est--dire des instructions de la forme : chacun du mot (relativement arbitraire) class sous la forme template
// entree >> ..... ; <class ..., class ..., ...>. La dfinition de la fonction est classique, hor-
return entree ; mis le fait que les paramtres muets de type peuvent tre employs
} n'importe o un type effectif est permis.
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 065 13
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
template <class T, class U> void fct (T a, T * b, U c) template <class T> int compte (T * tab, int n)
{ { // ici, on peut se servir de la valeur de l'entier n
Tx; // variable locale x de type T // comme on le ferait dans n'importe quelle fonction ordinaire
U * adr ; // variable locale adr de type U * }
... Un patron de fonctions peut disposer d'un ou de plusieurs paramtres
adr = new T [10] ; // allocation tableau de 10 lments de type T expression. Lors de l'appel, leur type n'a plus besoin de correspondre
... exactement celui attendu : il suffit qu'il soit acceptable par affectation,
n = sizeof (T) ; // une instruction utilisant le type T comme dans n'importe quel appel d'une fonction ordinaire.
...
}
9.4 Surdfinition de patrons de fonctions
Remarque et spcialisation de fonctions
Une instruction telle que (T dsignant un type quelconque) : de patrons
T x (3) ;
On peut dfinir plusieurs patrons de mme nom, possdant des
est lgale mme si T n'est pas un type classe ; dans ce dernier paramtres (de type ou expression) diffrents. La seule rgle res-
cas, elle est simplement quivalente : pecter dans ce cas est que l'appel d'une fonction de ce nom ne doit
pas conduire une ambigut : un seul patron de fonctions doit pou-
Tx=3; voir tre utilis chaque fois.
Par ailleurs, il est possible de fournir la dfinition d'une ou plu-
sieurs fonctions particulires qui seront utilises en lieu et place de
9.2 Instanciation d'une fonction patron celle instancie par un patron.
template <class T> T min (T a, T b) // patron de fonctions
Chaque fois que l'on utilise une fonction ayant un nom de patron, { ... }
le compilateur cherche utiliser ce patron pour crer (instancier) char * min (char * cha, char * chb) // version spcialise
une fonction adquate. Pour ce faire, il cherche raliser une corres- { ... } // pour le type char *
pondance absolue des types : aucune conversion, qu'il s'agisse de int n, p;
promotion numrique ou de conversion standard n'est permise. char * adr1, * adr2 ;
min (n, p) // appelle la fonction
Voici des exemples utilisant notre patron prcdent. // instancie par
int n, p ; float x ; char c ; // le patron gnral, soit ici :
int * adi ; float * adf ; // int min (int, int)
class point ; point p ; point * adp ; min (adr1, adr2) // appelle la fonction
// spcialise :
fct (n, adi, x) ; // instancie la fonction : // char * min (char *, char *)
// void fct (int, int *, float)
fct (n, adi, p) // instancie la fonction :
// void fct (int, int *, int) 9.5 Algorithme d'instanciation
fct (x, adf, p) ; // instancie la fonction : ou d'appel d'une fonction
// void fct (float, float *, int)
fct (c, adi, x) ; // erreur char et int * ne correspondent
Prcisons comment doivent tre amnages les rgles de recher-
// pas T et T* ( pas de conversion)
che d'une fonction surdfinie, dans le cas o il existe un ou plu-
fct (&n, &adi, x) ; // instancie la fonction :
sieurs patrons de fonctions.
// void fct (int *, int * *, float)
fct (p, adp, n) ; // instancie la fonction : Lors d'un appel de fonction, le compilateur recherche tout
// void fct (point, point *, int) d'abord une correspondance exacte (mme nombre et mmes
types dargument) avec les fonctions ordinaires . S'il y a ambi-
D'une manire gnrale, il est ncessaire que chaque paramtre gut, la recherche choue (comme l'accoutume). Si aucune fonc-
de type apparaisse au moins une fois dans l'en-tte du patron. tion ordinaire ne convient, on examine alors tous les patrons
ayant le nom voulu (en ne considrant que les paramtres de type).
Si une seule correspondance exacte est trouve, la fonction corres-
Remarque pondante est instancie et le problme est rsolu. S'il y en a plu-
La dfinition d'un patron de fonctions ne peut pas tre compi- sieurs, la recherche choue.
le seule ; de toute faon, elle doit tre connue du compilateur
pour qu'il puisse instancier la bonne fonction patron. En gn- Enfin, si aucun patron de fonction ne convient, on examine nou-
ral, les dfinitions de patrons de fonctions figureront dans des veau toutes les fonctions ordinaires en les traitant cette fois
fichiers d'extension h, de faon viter d'avoir en fournir sys- comme de simples fonctions surdfinies (promotions numriques,
tmatiquement la liste. conversions standard...).
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 14 Techniques de lIngnieur, trait Informatique industrielle
______________________________________________________________________________________________________ PROGRAMMATION EN LANGAGE C++
On dclare une classe patron en fournissant la suite du nom de 10.4 Identit de classes patron
patron un nombre de paramtres effectifs (noms de types ou
expressions) correspondant aux paramtres figurant dans la liste
(template). Les paramtres expression doivent obligatoirement tre On ne peut affecter entre eux que deux objets de mme type.
des expressions constantes du mme type que celui figurant dans la Dans le cas d'objets d'un type classe patron, on considre qu'il y a
liste. identit de type lorsque leurs paramtres de types sont identiques
et que les paramtres expression ont les mmes valeurs.
Exemple : avec notre prcdent patron (on suppose que pt est une
classe) :
class gene <int, float, 5> c1 ; // T = int, U = float, n=5 10.5 Classes patron et hritage
class gene <int, int, 12> c2 ; // T = int, U = int, n = 12
const int NV=100 ;
class gene <pt, double, NV> c3 ; // T = pt, U = double, n=100 On peut combiner de plusieurs faons l'hritage avec la notion
int n = 5 ; de patron de classes.
class gene <int, double, n> c4 ; // erreur : n n'est pas constant
const char C = 'e' ; Classe ordinaire drive d'une classe patron
class gene <int, double, C> c5 ; // erreur : C de type char et non int Par exemple, si A est une classe patron dfinie par template
<class T> A :
Un paramtre de type effectif peut lui-mme tre une classe
class B : public A <int> // B drive de la classe patron A<int>
patron. Par exemple, si nous avons dfini un patron de classes point
par : on obtient une seule classe nomme B.
template <class T> class point { ..... } ; Patron de classes driv d'une classe ordinaire
Voici des instances possibles de gene : Par exemple, si A est une classe ordinaire :
class gene <point<int>, float, 10> c5 ;
template <class T> class B : public A
// T=point<int>, U=float, n=10
class gene <point<char>, point<float>, 5> c6 ; on obtient une famille de classes (de paramtre de type T).
// T=point<int>, U=point<float>, n=5 Patron de classes driv d'un patron de classes
Un patron de classes peut comporter des membres (donnes ou Par exemple, si A est une classe patron dfinie par template
fonctions) statiques ; dans ce cas, chaque instance de la classe dis- <class T> A, on peut :
pose de son propre jeu de membres statiques. dfinir une nouvelle famille de fonctions drives par :
template <class T> class B : public A <T>
10.3 Spcialisation d'un patron Dans ce cas, il existe autant de classes drives possibles que de
classes de base possibles.
de classes
dfinir une nouvelle famille de fonctions drives par :
template <class T, class U> class B : public A <T>
Un patron de classes ne peut pas tre surdfini (on ne peut pas
dfinir deux patrons de mme nom). En revanche, on peut spciali- Dans ce cas, on peut dire que chaque classe de base possible peut
ser un patron de classes de diffrentes manires. engendrer une famille de classes drives (de paramtre de type U).
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
Techniques de lIngnieur, trait Informatique industrielle S 8 065 15
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 16 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 065 17
PROGRAMMATION EN LANGAGE C++ ______________________________________________________________________________________________________
Rfrences bibliographiques
[1] MEYER (B.). Object-Oriented Software [4] LIPPMAN (S.B.). C++ Primer, Third Edition. [6] DELANNOY (C.). Exercices en langage C++,
Construction. C.A.R. Hare Series Editor, Reading, MA : Addison-Welsley Publishing nouvelle dition. dition Eyrolles, 61, boule-
Englewood Cliffs, NJ: Prentice Hall, 1988. Company, 1998. vard St Germain 75240 Paris, 2002.
[2] STROUSTRUP (B.). The C++ Programming
Langage, Third Edition. Reading, MA : Addi-
son-Welsley Publishing Company, 1997. [5] DELANNOY (C.). Programmer en langage [7] Revue spcialise : The C/C++ Users Journal
[3] STROUSTRUP (B.). Le langage C++, Troi- C++, cinquime dition. ditions Eyrolles, 61 (advanced solutions for C/C++ program-
sime dition. CampusPress France, 1999. boulevard St Germain 75240 Paris, 2002. mers). Site internet : http://www.cuj.com
Toute reproduction sans autorisation du Centre franais dexploitation du droit de copie est strictement interdite.
S 8 065 18 Techniques de lIngnieur, trait Informatique industrielle