ChristianCasteyde
CoursdeC/C++
parChristianCasteyde
Copyright2003ChristianCasteyde
Permissionisgrantedtocopy,distributeand/ormodifythisdocumentunderthetermsoftheGNUFreeDocumentationLicense,Version1.1
oranylaterversionpublishedbytheFreeSoftwareFoundation;withnoInvariantSections,withnoFrontCoverTexts,andwithno
BackCoverTexts.
Acopyofthelicenseisincludedinthesectionentitled"GNUFreeDocumentationLicense".
Permissionvousestdonnedecopier,distribueretmodifiercedocumentselonlestermesdelalicenceGNUpourlesdocumentationslibres,
version1.1outouteautreversionultrieurepublieparlaFreeSoftwareFoundation.
Unecopiedecettelicenceestinclusedanslannexeintitule"GNUFreeDocumentationLicense".Voustrouverezgalementunetraduction
nonofficielledecettelicencedanslannexeintitule"LicencededocumentationlibreGNU".
Historiquedesversions
Version1.32
17/06/2000/ Revupar:CC
Correctionduneerreurdansleprogrammedexempledupremierchapitre.Correctionduneerreurdansunexemplesurlad rivat
Version1.31
12/02/2000 Revupar:CC
Correctionsmineurs.Ajoutduparagraphesurlaspcialisationdunefonctionmembreduneclassetemplate.
Version1.30
05/12/1999 Revupar:CC
Ajoutdelalicence.Modificationsmineuresduformatage.
Version <1.30 <1998
Revupar:CC
Versioninitiale.
Tabledesmatires
Avantpropos.........................................................................................................................
I.LelangageC++....................................................................................................................
1.PremireapprocheduC/C++..............................................................................................
1.1.LescommentairesenC++........................................................................................
1.2.LestypesprdfinisduC/C++...................................................................................2
1.3.Notationdesvaleurs...............................................................................................
1.4.Ladfinitiondesvariables.......................................................................................
1.5.Instructionsetoprations..........................................................................................
1.6.Lesfonctions.......................................................................................................
1.6.1.Dfinitiondesfonctions...............................................................................12
1.6.2.Appeldesfonctions......................................................................................13
1.6.3.Dclarationdesfonctions.............................................................................13
1.6.4.Surchargedesfonctions...............................................................................14
1.6.5.Fonctionsinline............................................................................................
1.6.6.Fonctionsstatiques.......................................................................................1
1.6.7.Fonctionsprenantunnombrevariabledeparamtres.................................16
1.7.Lafonctionmain.......................................................................................................18
1.8.Lesfonctionsdentre/sortiedebase.....................................................................19
1.8.1.Gnralitssurlesfluxdentre/sortieenC..............................................19
1.8.2.Lafonctionprintf.........................................................................................2
1.8.3.Lafonctionscanf..........................................................................................23
1.9.Exempledeprogrammecomplet..............................................................................24
2.Lesstructuresdecontrle...................................................................................................
2.1.Lastructureconditionnelleif....................................................................................25
2.2.Labouclefor........................................................................................................
2.3.Lewhile.............................................................................................................
2.4.Ledo.................................................................................................................
2.5.Lebranchementconditionnel...................................................................................28
2.6.Lesaut...............................................................................................................
2.7.Lescommandesderupturedesquence..................................................................29
3.Typesavancsetclassesdestockage....................................................................................3
3.1.Structuresdedonnesettypescomplexes................................................................31
3.1.1.Lesstructures...............................................................................................
3.1.2.Lesunions.................................................................................................
3.1.3.Lesnumrations.........................................................................................3
3.1.4.Leschampsdebits.......................................................................................3
3.1.5.Initialisationdesstructuresetdestableaux..................................................36
3.1.6.Lesaliasdetypes.........................................................................................3
3.1.7.Transtypages...............................................................................................
3.2.Lesclassesdestockage............................................................................................
4.Lespointeursetrfrences................................................................................................
4.1.Notiondadresse...................................................................................................
4.2.Notiondepointeur.................................................................................................
4.3.Drfrencement,indirection...................................................................................44
4.4.Notionderfrence.................................................................................................
4.5.Lienentrelespointeursetlesrfrences..................................................................46
4.6.Passagedeparamtresparvariableouparvaleur....................................................47
4.6.1.Passageparvaleur........................................................................................
4.6.2.Passageparvariable.....................................................................................4
4.6.3.Avantagesetinconvnientsdesdeuxmthodes...........................................48
4.6.4.CommentpasserlesparamtresparvariableenC?....................................49
4.6.5.Passagedeparamtresparrfrence............................................................49
4.7.Rfrencesetpointeursconstantsetvolatiles..........................................................51
4.8.Arithmtiquedespointeurs.......................................................................................54
4.9.Utilisationdespointeursaveclestableaux...............................................................55
4.9.1.Conversionsdestableauxenpointeurs........................................................55
4.9.2.Paramtresdefonctiondetypetableau.......................................................56
4.10.Leschanesdecaractres:pointeursettableauxlafois!...................................57
4.11.Allocationdynamiquedemmoire........................................................................58
4.11.1.AllocationdynamiquedemmoireenC...................................................58
4.11.2.AllocationdynamiqueenC++...................................................................63
4.12.Pointeursetrfrencesdefonctions.......................................................................65
4.12.1.Pointeursdefonctions................................................................................65
4.12.2.Rfrencesdefonctions.............................................................................67
4.13.Paramtresdelafonctionmainlignedecommande............................................68
4.14.DANGER.........................................................................................................
5.LeprprocesseurC.........................................................................................................
5.1.Dfinition...........................................................................................................
5.2.Lescommandesduprprocesseur............................................................................71
5.2.1.Inclusiondefichier.......................................................................................
5.2.2.Constantesdecompilationetremplacementdetexte..................................72
5.2.3.Compilationconditionnelle..........................................................................73
5.2.4.Autrescommandes.......................................................................................7
5.3.Lesmacros..........................................................................................................
5.4.Manipulationdechanesdecaractresdanslesmacros...........................................76
5.5.Lestrigraphes.......................................................................................................
6.Modularitdesprogrammesetgnrationdesbinaires........................................................79
6.1.Pourquoifaireuneprogrammationmodulaire?.......................................................79
6.2.Lesdiffrentesphasesduprocessusdegnrationdesexcutables.........................79
6.3.CompilationspareenC/C++................................................................................82
6.4.Syntaxedesoutilsdecompilation............................................................................83
6.4.1.Syntaxedescompilateurs.............................................................................83
6.4.2.Syntaxedemake..........................................................................................
6.5.Problmessyntaxiquesrelatifslacompilationspare.........................................85
6.5.1.Dclarationdestypes...................................................................................85
6.5.2.Dclarationdesvariables.............................................................................86
6.5.3.Dclarationdesfonctions.............................................................................86
6.5.4.Directivesdditiondeliens........................................................................86
7.Commentfaireducodeillisible?.........................................................................................8
8.C++:lacoucheobjet.......................................................................................................
8.1.Gnralits..........................................................................................................
8.2.ExtensiondelanotiondetypeduC.........................................................................92
8.3.DclarationdeclassesenC++..................................................................................9
8.4.Encapsulationdesdonnes.......................................................................................9
8.5.Hritage.............................................................................................................
8.6.Classesvirtuelles...................................................................................................
8.7.Fonctionsetclassesamies......................................................................................1
8.7.1.Fonctionsamies.........................................................................................1
8.7.2.Classesamies.............................................................................................1
8.8.Constructeursetdestructeurs..................................................................................10
8.8.1.Dfinitiondesconstructeursetdesdestructeurs........................................104
vi
8.8.2.Constructeursdecopie...............................................................................109
8.8.3.Utilisationdesconstructeursdanslestranstypages...................................110
8.9.Pointeurthis.........................................................................................................
8.10.Donnesetfonctionsmembresstatiques..............................................................112
8.10.1.Donnesmembresstatiques.....................................................................112
8.10.2.Fonctionsmembresstatiques...................................................................113
8.11.Surchargedesoprateurs......................................................................................1
8.11.1.Surchargedesoprateursinternes............................................................115
8.11.2.Surchargedesoprateursexternes...........................................................118
8.11.3.Oprateursdaffectation...........................................................................120
8.11.4.Oprateursdetranstypage........................................................................122
8.11.5.Oprateursdecomparaison......................................................................122
8.11.6.Oprateursdincrmentationetdedcrmentation.................................123
8.11.7.Oprateurfonctionnel..............................................................................123
8.11.8.Oprateursdindirectionetdedrfrencement......................................126
8.11.9.Oprateursdallocationdynamiquedemmoire.....................................127
8.12.Desentressortiessimplifies...........................................................................133
8.13.Mthodesvirtuelles..............................................................................................
8.14.Drivation.........................................................................................................
8.15.MthodesvirtuellespuresClassesabstraites.....................................................140
8.16.Pointeurssurlesmembresduneclasse...............................................................145
9.LesexceptionsenC++.......................................................................................................
9.1.Lancementetrcuprationduneexception...........................................................150
9.2.Remontedesexceptions........................................................................................1
9.3.Listedesexceptionsautorisespourunefonction.................................................154
9.4.Hirarchiedesexceptions.......................................................................................15
9.5.Exceptionsdanslesconstructeurs..........................................................................157
10.Identificationdynamiquedestypes...................................................................................1
10.1.Identificationdynamiquedestypes......................................................................161
10.1.1.Loprateurtypeid....................................................................................16
10.1.2.Laclassetype_info..................................................................................16
10.2.TranstypagesC++................................................................................................
10.2.1.Transtypagedynamique...........................................................................164
10.2.2.Transtypagestatique................................................................................16
10.2.3.Transtypagedeconstanceetdevolatilit.................................................167
10.2.4.Rinterprtationdesdonnes...................................................................167
11.Lesespacesdenommage.................................................................................................
11.1.Dfinitiondesespacesdenommage.....................................................................169
11.1.1.Espacesdenommagenommes...............................................................169
11.1.2.Espacesdenommageanonymes..............................................................171
11.1.3.Aliasdespacesdenommage...................................................................172
11.2.Dclarationusing.................................................................................................
11.2.1.Syntaxedesdclarationsusing................................................................172
11.2.2.Utilisationdesdclarationsusingdanslesclasses..................................174
11.3.Directiveusing....................................................................................................
12.Lestemplate................................................................................................................
12.1.Gnralits.........................................................................................................
12.2.Dclarationdesparamtrestemplate....................................................................179
12.2.1.Dclarationdestypestemplate................................................................179
12.2.2.Dclarationdesconstantestemplate........................................................180
12.3.Fonctionsetclassestemplate................................................................................18
12.3.1.Fonctionstemplate...................................................................................18
vii
12.3.2.Lesclassestemplate.................................................................................182
12.3.3.Fonctionsmembrestemplate...................................................................185
12.4.Instanciationdestemplate....................................................................................18
12.4.1.Instanciationimplicite..............................................................................188
12.4.2.Instanciationexplicite..............................................................................189
12.4.3.Problmessoulevsparlinstanciationdestemplate...............................190
12.5.Spcialisationdestemplate...................................................................................191
12.5.1.Spcialisationtotale.................................................................................191
12.5.2.Spcialisationpartielle.............................................................................192
12.5.3.Spcialisationdunemthodeduneclassetemplate...............................194
12.6.Motcltypename.................................................................................................
12.7.Fonctionsexportes..............................................................................................
II.LabibliothquestandardC++.................................................................................................
13.Servicesetnotionsdebasedelabibliothquestandard...................................................199
13.1.EncapsulationdelabibliothqueCstandard........................................................199
13.2.Dfinitiondesexceptionsstandards.....................................................................201
13.3.Abstractiondestypesdedonnes:lestraits........................................................204
13.4.Abstractiondespointeurs:lesitrateurs..............................................................206
13.4.1.Notionsdebaseetdfinition....................................................................206
13.4.2.Classificationdesitrateurs......................................................................207
13.4.3.Itrateursadaptateurs...............................................................................209
13.4.3.1.Adaptateurspourlesfluxdentre/sortiestandards..................210
13.4.3.2.Adaptateurspourlinsertiondlmentsdanslesconteneurs.....212
13.4.3.3.Itrateurinversepourlesitrateursbidirectionnels.....................215
13.5.Abstractiondesfonctions:lesfoncteurs..............................................................217
13.5.1.Foncteursprdfinis.................................................................................217
13.5.2.Prdicatsetfoncteursdoprateurslogiques............................................222
13.5.3.Foncteursrducteurs................................................................................22
13.6.Gestionpersonnalisedelammoire:lesallocateurs.........................................225
13.7.Notiondecomplexitalgorithmique....................................................................229
13.7.1.Gnralits...............................................................................................
13.7.2.Notionsmathmatiquesdebaseetdfinition...........................................230
13.7.3.Interprtationpratiquedelacomplexit..................................................231
14.Lestypescomplmentaires...............................................................................................
14.1.Leschanesdecaractres......................................................................................233
14.1.1.Constructionetinitialisationdunechane..............................................237
14.1.2.Accsauxpropritsdunechane..........................................................238
14.1.3.Modificationdelatailledeschanes........................................................239
14.1.4.Accsauxdonnesdelachanedecaractres.........................................240
14.1.5.Oprationssurleschanes........................................................................242
14.1.5.1.Affectationetconcatnationdechanesdecaractres................242
14.1.5.2.Extractiondedonnesdunechanedecaractres......................244
14.1.5.3.Insertionetsuppressiondecaractresdansunechane...............245
14.1.5.4.Remplacementsdecaractresdunechane................................246
14.1.6.Comparaisondechanesdecaractres.....................................................248
14.1.7.Recherchedansleschanes......................................................................249
14.1.8.Fonctionsdentre/sortiedeschanesdecaractres...............................251
14.2.Lestypesutilitaires...............................................................................................
14.2.1.Lespointeursauto....................................................................................25
14.2.2.Lespaires.................................................................................................
14.3.Lestypesnumriques...........................................................................................2
viii
14.3.1.Lescomplexes..........................................................................................257
14.3.1.1.Dfinitionetprincipalespropritsdesnombrescomplexes......257
14.3.1.2.Laclassecomplex.......................................................................259
14.3.2.Lestableauxdevaleurs............................................................................262
14.3.2.1.Fonctionnalitsdebasedesvalarray...........................................263
14.3.2.2.Slectionmultipledeslmentsdunvalarray............................267
14.3.2.2.1.Slectionparunmasque.................................................267
14.3.2.2.2.Slectionparindexationexplicite...................................268
14.3.2.2.3.Slectionparindexationimplicite..................................269
14.3.2.2.4.Oprationsralisablessurlesslectionsmultiples.........271
14.3.3.Leschampsdebits...................................................................................27
15.Lesfluxdentre/sortie..................................................................................................
15.1.Notionsdebaseetprsentationgnrale..............................................................277
15.2.Lestampons.......................................................................................................
15.2.1.Gnralitssurlestampons.....................................................................279
15.2.2.Laclassebasic_streambuf........................................................................280
15.2.3.Lesclassesdetamponsbasic_streambufetbasic_filebuf........................285
15.2.3.1.Laclassebasic_stringbuf.............................................................286
15.2.3.2.Laclassebasic_filebuf.................................................................288
15.3.Lesclassesdebasedesflux:ios_baseetbasic_ios.............................................289
15.3.1.Laclasseios_base....................................................................................29
15.3.2.Laclassebasic_ios...................................................................................29
15.4.Lesfluxdentre/sortie.......................................................................................29
15.4.1.Laclassedebasebasic_ostream..............................................................299
15.4.2.Laclassedebasebasic_istream...............................................................305
15.4.3.Laclassebasic_iostream..........................................................................311
15.5.Lesfluxdentre/sortiesurchanesdecaractres..............................................312
15.6.Lesfluxdentre/sortiesurfichiers....................................................................313
16.Leslocales..................................................................................................................
16.1.Notionsdebaseetprincipedefonctionnementdesfacettes................................318
16.2.Lesfacettesstandards...........................................................................................3
16.2.1.Gnralits...............................................................................................
16.2.2.Lesfacettesdemanipulationdescaractres............................................324
16.2.2.1.Lafacettectype...........................................................................324
16.2.2.2.Lafacettecodecvt........................................................................328
16.2.3.Lesfacettesdecomparaisondechanes...................................................332
16.2.4.Lesfacettesdegestiondesnombres........................................................335
16.2.4.1.Lafacettenum_punct..................................................................335
16.2.4.2.Lafacettedcrituredesnombres...............................................337
16.2.4.3.Lafacettedelecturedesnombres...............................................338
16.2.5.Lesfacettesdegestiondesmonnaies.......................................................339
16.2.5.1.Lafacettemoney_punct..............................................................340
16.2.5.2.Lesfacettesdelectureetdcrituredesmontants.......................342
16.2.6.Lesfacettesdegestiondutemps..............................................................343
16.2.6.1.Lafacettedcrituredesdates.....................................................345
16.2.6.2.Lafacettedelecturedesdates.....................................................345
16.2.7.Lesfacettesdegestiondesmessages.......................................................347
16.3.Personnalisationdesmcanismesdelocalisation.................................................349
16.3.1.Crationetintgrationdunenouvellefacette.........................................349
16.3.2.Remplacementdunefacetteexistante.....................................................353
17.Lesconteneurs.............................................................................................................
17.1.Fonctionnalitsgnralesdesconteneurs.............................................................357
ix
17.1.1.Dfinitiondesitrateurs...........................................................................358
17.1.2.Dfinitiondestypesdedonnesrelatifsauxobjetscontenus..................359
17.1.3.Spcificationdelallocateurmmoireutiliser.......................................359
17.1.4.Oprateursdecomparaisondesconteneurs.............................................360
17.1.5.Mthodesdintrtgnral......................................................................361
17.2.Lessquences.....................................................................................................
17.2.1.Fonctionnalitscommunes.......................................................................361
17.2.1.1.Constructionetinitialisation.......................................................361
17.2.1.2.Ajoutetsuppressiondlments.................................................363
17.2.2.Lesdiffrentstypesdesquences............................................................364
17.2.2.1.Leslistes......................................................................................3
17.2.2.2.Lesvecteurs.................................................................................368
17.2.2.3.Lesdeques...................................................................................37
17.2.2.4.Lesadaptateursdesquences......................................................371
17.2.2.4.1.Lespiles..........................................................................371
17.2.2.4.2.Lesfiles...........................................................................372
17.2.2.4.3.Lesfilesdepriorits........................................................372
17.3.Lesconteneursassociatifs....................................................................................37
17.3.1.Gnralitsetpropritsdebasedesclefs...............................................375
17.3.2.Constructionetinitialisation....................................................................376
17.3.3.Ajoutetsuppressiondlments..............................................................377
17.3.4.Fonctionsderecherche............................................................................379
18.Lesalgorithmes.............................................................................................................
18.1.Oprationsgnralesdemanipulationdesdonnes.............................................385
18.1.1.Oprationsdinitialisationetderemplissage...........................................386
18.1.2.Oprationsdecopie..................................................................................387
18.1.3.Oprationsdchangedlments............................................................388
18.1.4.Oprationsdesuppressiondlments.....................................................389
18.1.5.Oprationsderemplacement....................................................................391
18.1.6.Rorganisationdesquences...................................................................392
18.1.6.1.Oprationsderotationetdepermutation....................................393
18.1.6.2.Oprationsdinversion................................................................394
18.1.6.3.Oprationsdemlange................................................................395
18.1.7.Algorithmesditrationetdetransformation...........................................396
18.2.Oprationsderecherche.......................................................................................40
18.2.1.Oprationderecherchedlments..........................................................401
18.2.2.Oprationsderecherchedemotifs...........................................................403
18.3.Oprationsdordonnancement..............................................................................405
18.3.1.Oprationsdegestiondestas...................................................................406
18.3.2.Oprationsdetri.......................................................................................4
18.3.3.Oprationsderecherchebinaire...............................................................412
18.4.Oprationsdecomparaison..................................................................................41
18.5.Oprationsensemblistes.......................................................................................41
18.5.1.Oprationsdinclusion.............................................................................417
18.5.2.Oprationsdintersection.........................................................................418
18.5.3.Oprationsdunionetdefusion...............................................................420
18.5.4.Oprationsdediffrence..........................................................................422
18.5.5.Oprationsdepartitionnement.................................................................424
19.Conclusion........................................................................................................................
A.Prioritsdesoprateurs.............................................................................................................429
B.DraftPapers.......................................................................................................................
C.GNUFreeDocumentationLicense...........................................................................................4
D.LicencededocumentationlibreGNU......................................................................................4
BIBLIOGRAPHIE..................................................................................................................
xi
xii
Listedestableaux
11.Typespourleschanesdeformatde printf..............................................................................21
12.Optionspourlestypesdeschanesdeformat.............................................................................22
21.Oprateursdecomparaison.....................................................................................................
22.Oprateurslogiques..............................................................................................................
51.Trigraphes.......................................................................................................................
81.Droitsdaccssurlesmembreshrits.......................................................................................9
141.Fonctionsderecherchedansleschanesdecaractres...........................................................249
142.Fonctionsspcifiquesauxcomplexes......................................................................................2
151.Optionsdeformatagedesflux................................................................................................
152.Modesdouverturedesfichiers...............................................................................................
153.Directionsdedplacementdansunfichier..............................................................................293
154.tatsdesfluxdentre/sortie.................................................................................................
155.Manipulateursdesfluxdesortie..............................................................................................
156.Manipulateursutilisantdesparamtres...................................................................................30
157.Manipulateursdesfluxdentre..............................................................................................
161.FonctionsCdegestiondesdates.............................................................................................
171.Mthodesspcifiquesauxlistes..............................................................................................
A1.Oprateursdulangage..........................................................................................................
Listedesillustrations
41.Notiondepointeuretdadresse................................................................................................
61.Processusdegnrationdesbinaires...........................................................................................80
Listedesexemples
11.CommentaireC...................................................................................................................
12.CommentaireC++................................................................................................................
13.Typessignsetnonsigns......................................................................................................
14.Notationdesentiersenbase10.................................................................................................
15.Notationdesentiersenbase16.................................................................................................
16.Notationdesentiersenbase8...................................................................................................
17.Notationdesrels................................................................................................................
18.Dfinitiondevariables..........................................................................................................
19.Dfinitionduntableau.........................................................................................................
110.Instructionvide.................................................................................................................
111.Affectationcompose.........................................................................................................
112.Instructioncompose..........................................................................................................
113.Dfinitiondefonction.........................................................................................................
114.Dfinitiondeprocdure........................................................................................................
115.Appeldefonction...............................................................................................................
116.Dclarationdefonction.........................................................................................................
117.Surchargedefonctions.........................................................................................................
118.Fonctioninline.................................................................................................................
119.Fonctionstatique................................................................................................................
120.Fonctionnombredeparamtresvariable................................................................................18
121.Programmeminimal...........................................................................................................
xiii
122.Utilisationdeprintfetfprintf.................................................................................................
123.Programmecompletsimple....................................................................................................
21.Testconditionnelif...............................................................................................................
22.Bouclefor........................................................................................................................
23.Bouclewhile.....................................................................................................................
24.Boucledo.........................................................................................................................
25.Branchementconditionnelswitch...............................................................................................
26.Rupturedesquenceparcontinue..............................................................................................
31.Dclarationdevariabledetypestructure....................................................................................3
32.Dclarationdestructure...............................................................................................................32
33.Dclarationduneunion.........................................................................................................
34.Unionavecdiscriminant........................................................................................................
35.Dclarationdunenumration.................................................................................................
36.Dclarationdunchampsdebits...............................................................................................
37.Initialisationdunestructure....................................................................................................
38.InitialisationdestructureC99...................................................................................................
39.Dfinitiondetypesimple.......................................................................................................
310.Dfinitiondetypetableau..........................................................................................................37
311.Dfinitiondetypestructure.....................................................................................................
312.TranstypageenC...............................................................................................................
313.Dclarationdunevariablelocalestatique................................................................................40
314.Dclarationdunevariableconstante........................................................................................
315.Dclarationdeconstanteexternes.............................................................................................
316.Utilisationdumotclmutable.................................................................................................
41.Dclarationdepointeurs........................................................................................................
42.Utilisationdepointeursdestructures..........................................................................................
43.Dclarationderfrences.......................................................................................................
44.Passagedeparamtreparvaleur................................................................................................
45.PassagedeparamtreparvariableenPascal...............................................................................4
46.PassagedeparamtreparvariableenC......................................................................................4
47.PassagedeparamtreparrfrenceenC++................................................................................50
48.Passagedeparamtresconstantparrfrence.............................................................................50
49.Crationdunobjettemporairelorsdunpassageparrfrence.................................................50
410.Arithmtiquedespointeurs.....................................................................................................
411.Accsauxlmentsduntableauparpointeurs........................................................................56
412.Passagedetableauenparamtre...............................................................................................
413.AllocationdynamiquedemmoireenC...................................................................................59
414.Dclarationdepointeurdefonction..........................................................................................
415.Drfrencementdepointeurdefonction.................................................................................66
416.Applicationdespointeursdefonctions.....................................................................................6
417.Rcuprationdelalignedecommande.....................................................................................
51.Dfinitiondeconstantesdecompilation.....................................................................................7
52.MacrosMINetMAX...........................................................................................................
61.Compilationdunfichieretditiondeliens................................................................................84
62.Fichiermakefilesansdpendances............................................................................................
63.Fichiermakefileavecdpendances.............................................................................................
64.DclarationsutilisablesenCetenC++......................................................................................8
71.Programmeparfaitementillisible...............................................................................................
81.Dclarationdemthodesdeclasse.............................................................................................
82.Oprateurdersolutiondeporte...............................................................................................
83.Utilisationdeschampsduneclassedansunedesesmthodes..................................................94
84.Utilisationdumotclclass.....................................................................................................
xiv
85.Hritagepublic,privetprotg...............................................................................................
86.Oprateurdersolutiondeporteetmembredeclassesdebase..............................................100
87.Classesvirtuelles.................................................................................................................
88.Fonctionsamies..................................................................................................................
89.Classeamie.......................................................................................................................
810.Constructeursetdestructeurs...................................................................................................105
811.Appelduconstructeurdesclassesdebase..............................................................................106
812.Initialisationdedonnesmembresconstantes.........................................................................108
813.Donnemembrestatique.......................................................................................................
814.Fonctionmembrestatique.....................................................................................................
815.Appeldefonctionmembrestatique.........................................................................................114
816.Surchargedesoprateursinternes...........................................................................................1
817.Surchargedoprateursexternes..............................................................................................
818.Oprateursdincrmentationetdedcrmentation.................................................................123
819.Implmentationduneclassematrice......................................................................................1
820.Oprateurdedrfrencementetdindirection.......................................................................126
821.Dterminationdelatailledelenttedestableaux................................................................127
822.Oprateursnewavecplacement..............................................................................................
823.Utilisationdenewsansexception...........................................................................................1
824.Fluxdentre/sortiecinetcout..............................................................................................
825.Redfinitiondemthodedeclassedebase.............................................................................136
826.Conteneurdobjetspolymorphiques.......................................................................................14
827.Pointeurssurmembresstatiques.............................................................................................1
91.Utilisationdesexceptions......................................................................................................
92.Installationdungestionnairedexceptionavecset_terminate..................................................153
93.Gestiondelalistedesexceptionsautorises.............................................................................155
94.Classificationdesexceptions....................................................................................................
95.Exceptionsdanslesconstructeurs.............................................................................................1
101.Oprateurtypeid................................................................................................................
102.Oprateurdynamic_cast.......................................................................................................
111.Extensiondenamespace......................................................................................................
112.Accsauxmembresdunnamespace......................................................................................1
113.Dfinitionexternedunefonctiondenamespace....................................................................170
114.Dfinitiondenamespacedansunnamespace..........................................................................170
115.Dfinitiondenamespaceanonyme..........................................................................................1
116.Ambigutsentrenamespaces.................................................................................................
117.Dclarationusing...............................................................................................................
118.Dclarationsusingmultiples...................................................................................................
119.Extensiondenamespaceaprsunedclarationusing.............................................................173
1110.Conflitentredclarationsusingetidentificateurslocaux......................................................174
1111.Dclarationusingdansuneclasse.........................................................................................1
1112.Rtablissementdedroitsdaccslaidedunedirectiveusing...........................................175
1113.Directiveusing................................................................................................................
1114.Extensiondenamespaceaprsunedirectiveusing...............................................................176
1115.Conflitentredirectiveusingetidentificateurslocaux...........................................................177
121.Dclarationdeparamtrestemplate........................................................................................1
122.Dclarationdeparamtretemplatetemplate...........................................................................180
123.Dclarationdeparamtrestemplatedetypeconstante...........................................................181
124.Dfinitiondefonctiontemplate..............................................................................................
125.Dfinitiondunepiletemplate................................................................................................
126.Fonctionmembretemplate.....................................................................................................
127.Fonctionmembretemplateduneclassetemplate..................................................................186
xv
128.Fonctionmembretemplateetfonctionmembrevirtuelle.......................................................187
129.Surchargedefonctionmembreparunefonctionmembretemplate........................................187
1210.Instanciationimplicitedefonctiontemplate.........................................................................188
1211.Instanciationexplicitedeclassetemplate.............................................................................190
1212.Spcialisationtotale..........................................................................................................
1213.Spcialisationpartielle.......................................................................................................
1214.Spcialisationdefonctionmembredeclassetemplate.........................................................194
1215.Motcltypename.............................................................................................................
1216.Motclexport.................................................................................................................
131.Dterminationdeslimitesduntype.......................................................................................20
132.Itrateursdefluxdentre......................................................................................................
133.Itrateurdefluxdesortie......................................................................................................
134.Itrateurdinsertion.............................................................................................................
135.Utilisationdunitrateurinverse.............................................................................................2
136.Utilisationdesfoncteursprdfinis.........................................................................................2
137.Adaptateursdefonctions.......................................................................................................
138.Rductiondefoncteursbinaires..............................................................................................
139.Utilisationdelallocateurstandard..........................................................................................227
141.Redimensionnementdunechane...........................................................................................239
142.Rservationdemmoiredansunechane...............................................................................240
143.Accsdirectauxdonnesdunechane...................................................................................2
144.Affectationdechanedecaractres.........................................................................................
145.Concatnationdechanesdecarctres....................................................................................24
146.Copiedetravaildesdonnesdunebasic_string.....................................................................244
147.Extractiondesouschane......................................................................................................
148.Insertiondecaractresdansunechane..................................................................................24
149.Suppressiondecaractresdansunechane.............................................................................246
1410.Remplacementdunesouschanedansunechane..............................................................247
1411.changeducontenudedeuxchanesdecaractres..............................................................247
1412.Comparaisonsdechanesdecaractres.................................................................................248
1413.Recherchesdansleschanesdecaractres............................................................................250
1414.Lecturedelignessurlefluxdentre....................................................................................25
1415.Utilisationdespointeursautomatiques..................................................................................253
1416.Sortiedunpointeurdunauto_ptr........................................................................................2
1417.Utilisationdespaires.........................................................................................................
1418.Manipulationdesnombrescomplexes..................................................................................26
1419.Modificationdelatailledunvalarray..................................................................................26
1420.Oprationssurlesvalarray...................................................................................................
1421.Dcalagesetrotationsdevaleurs..........................................................................................2
1422.Slectiondeslmentsdunvalarrayparunmasque............................................................268
1423.Slectiondeslmentsdunvalarrayparindexation............................................................269
1424.Slectionparindexationimplicite.........................................................................................2
1425.Utilisationdunbitset.........................................................................................................
1426.Manipulationdesbitsdunchampdebits.............................................................................275
151.Lectureetcrituredansuntampondechanedecaractres...................................................287
152.Lectureetcrituredansuntampondefichier.........................................................................289
153.Modificationdesoptionsdeformatagedesflux......................................................................295
154.Dfinitiondunnouveloprateurdinsertionpourunfluxdesortie.......................................301
155.criturededonnesbrutessurunfluxdesortie......................................................................302
156.Utilisationdesmanipulateurssurunfluxdesortie.................................................................305
157.crituredunnouveloprateurdextractionpourunfluxdentre.........................................307
158.Lecturesdelignessurlefluxdentrestandard......................................................................310
xvi
159.Utilisationdefluxdentre/sortiesurchanesdecaractres.................................................313
1510.Utilisationdefluxdentre/sortiesurunfichier..................................................................314
1511.Repositionnementdupointeurdefichierdansunfluxdentre/sortie................................315
161.ProgrammeC++prenantencomptelalocaledelenvironnement.........................................322
162.Conversiondunewstringenstring.........................................................................................
163.Conversiondunechanedecaractreslargesenchaneencodagevariable........................330
164.Dterminationdelalongueurdunechanedecaractresencodagevariable......................331
165.Comparaisondechanesdecaractreslocalises....................................................................334
166.Dfinitiondenouvellesfacettes...............................................................................................349
167.Spcialisationdunefacetteexistante......................................................................................3
171.Constructionetinitialisationduneliste..................................................................................36
172.Insertiondlmentsdansuneliste.........................................................................................3
173.Accslatteetlaqueueduneliste...................................................................................36
174.Manipulationdelistes.........................................................................................................
175.Accsauxlmentsdunvecteur............................................................................................
176.Utilisationdunepile...........................................................................................................
177.Utilisationdunefile...........................................................................................................
178.Utilisationdunefiledepriorit..............................................................................................
179.Constructionetinitialisationduneassociationsimple...........................................................376
1710.Insertionetsuppressiondlmentsduneassociation..........................................................378
1711.Recherchedansuneassociation............................................................................................
1712.Utilisationdunfoncteurdecomparaisonpersonnalis........................................................381
1713.Dfinitiondirectedufoncteurdecomparaisonpourlesrecherches.....................................382
181.Algorithmedegnrationdobjetsetderemplissagedunconteneur....................................386
182.Algorithmedecopieinverse..................................................................................................
183.Algorithmedchange.........................................................................................................
184.Algorithmedesuppression.....................................................................................................
185.Algorithmedesuppressiondesdoublons................................................................................39
186.Algorithmederechercheetderemplacement.........................................................................392
187.Algorithmederotation.........................................................................................................
188.Algorithmedepermutation.....................................................................................................
189.Algorithmedinversion............................................................................................................395
1810.Algorithmedemlange.......................................................................................................
1811.Algorithmesditration.......................................................................................................
1812.Algorithmededcomptedlments.....................................................................................3
1813.Algorithmedaccumulation..................................................................................................
1814.Algorithmedeproduitscalaire..............................................................................................
1815.Algorithmesdesommespartiellesetdediffrencesadjacentes...........................................401
1816.Algorithmederecherchedlments.....................................................................................4
1817.Algorithmesderecherchedemotif.......................................................................................40
1818.Algorithmederecherchededoublons...................................................................................4
1819.Algorithmesdemanipulationdestas....................................................................................40
1820.Algorithmedetri..............................................................................................................
1821.Algorithmedetripartiel.......................................................................................................
1822.Algorithmedepositionnementdunimelment.................................................................411
1823.Algorithmesdedterminationdumaximumetduminimum...............................................411
1824.Algorithmesdedterminationdesbornesinfrieuresetsuprieures....................................413
1825.Algorithmederecherchebinaire...........................................................................................4
1826.Algorithmedecomparaisondeconteneurs...........................................................................416
1827.Algorithmedecomparaisonlexicographique........................................................................417
1828.Algorithmededterminationdinclusion..............................................................................418
1829.Algorithmedintersectiondensembles.................................................................................419
xvii
1830.Algorithmesdunionetdefusiondensembles.....................................................................420
1831.Algorithmederunificationdedeuxsousensembles...........................................................421
1832.Algorithmesdediffrencedensembles................................................................................42
1833.Algorithmedepartitionnement.............................................................................................4
xviii
Avantpropos
CelivreestuncoursdeCetdeC++.
Ilsadresseauxpersonnesquiontdjquelquesnotionsde
programmationdansunlangagequelconque. Lesconnaissancesrequisesnesont pastrsleves
cependant:ilnestpasncessairedavoirfaitdegrandsprogrammespourlirecedocument.Ilsuffit
davoirvucequestunprogrammeetcomprislesgrandsprincipesdelaprogrammation.
Celivreeststructurendeuxgrandesparties,traitantchacuneundesaspectsduC++.Lapremire
partie,contenantleschapitres112,traitedulangageC++luimme,desasyntaxeetdesesprinci
palesfonctionnalits.LadeuximepartiequantelleseconcentresurlabibliothquestandardC++,
quifournitunensembledefonctionnalitscohrentesetrutilisablespartouslesprogrammeurs.La
bibliothquestandardC++agalementlavantagedutiliserlesconstructionslesplusavancesdu
langage,etillustredoncparfaitementlesnotionsquiauronttabordesdanslapremirepartie.La
descriptiondelabibliothquestandardstendduchapitre13auchapitre18.
SilabibliothquestandardC++estdcriteendtail,ilnenvapasdemmepourlesfonctionsde
labibliothqueC. Vousnetrouverezdoncpasdanscelivreladescriptiondesfonctionsclassiques
duC, ni celledesfonctionslespluscourantesdelanormePOSIX.
Eneffet, bienqueprsentes
surquasimenttouslessystmesdexploitation,cesfonctionssontspcifiqueslanormePOSIXet
nappartiennentpasaulangageensoi.SeuleslesfonctionsincontournablesdelabibliothqueCseront
doncprsentesici. Si vousdsirezplusderenseignements, reportezvousauxspcificationsdes
appelssystmesPOSIXdelOpenGroup(http://www.unixsystems.org/single_unix_specification/),
ouladocumentationdesenvironnementsdedveloppementetlaidedeskitsdedveloppement
dessystmesdexploitation(SDK).
Celivreapour but deprsenter lelangageC++tel quil est dcrit par lanormeISO14882
dulangageC++. Cependant, bienquecettenormeait
tpublieen1999, letexteofficiel
nest paslibrement disponible. Commejeneveuxpascautionner lefait quuntextedenorme
international nesoit pas accessibletous, jemesuis rabattusur ledocument duprojet de
normalisationdulangage, datant du2dcembre1996et
intitulWorkingPaper
for Draft
Proposed International Standard for Information Systems Programming Language C++
(http://casteyde.christian.free.fr/cpp/cours/drafts/index.html).
Notezquelescompilateursquirespectentcettenormesecomptentencoresurlesdoigtsdunemain,
etquelesinformationsetexemplesdonnsicipeuventnepassavrerexactsaveccertainsproduits.
Enparticulier,certainsexemplesnecompilerontpasaveclescompilateurslesplusmauvais.Notez
galementquecertainesconstructionsdulangagenontpaslammesignificationavectouslescom
pilateurs,parcequellesonttimplmentesavantquelanormenelesspcifiecompltement.Ces
diffrencespeuventconduireducodenonportable,etonttsignaleschaquefoisdansunenote.
Lefaitquelesexemplesdecelivrenefonctionnentpasavecdetelscompilateursnepeutdoncpas
treconsidrcommeuneerreur,maispluttcommeunenonconformitdesoutilsutiliss,quisera
sansdoutelevedanslesversionsultrieuresdecesproduits.
Aprsavoirtentdefaireuneprsentationrigoureusedusujet,jaidciddarrangerleplandece
livredansunordrepluspdagogique.Ilestmonavisimpossibledeparlerdunsujetuntantsoit
peuvastedansunordrepurementmathmatique,cestdireunordreolesnotionssontintroduites
uneune,partirdesnotionsdjconnues(chaquefonction,oprateur,etc.napparatpasavantsa
dfinition). Untelplanncessiteraitdecouperletexteenmorceauxquinesontplusthmatiques.
Jai doncprisladcisiondeprsenterleschosesparordrelogique, et nonparordredencessit
syntaxique.
Lesconsquencesdecechoixsontlessuivantes:
ilfautadmettrecertaineschoses,quittelescomprendreplustard;
Avantpropos
ilfautliredeuxfoiscelivre.Lorsdelapremirelecture,onvoitlessentiel,etlorsdeladeuxime
lecture,oncomprendlesdtails(detoutesmanires,jefliciteceluiquicomprendtouteslessubti
litsduC++dupremiercoup).
Enfin, ce livre est undocument vivant. Il est librement tlchargeable sur mon site web
(http://casteyde.christian.free.fr),oladernireversionpeuttrercupre.Touteremarqueestdonc
labienvenue.Jetcheraidecorrigerleserreursquelonmesignaleradanslamesuredupossible,et
dapporterlesmodificationsncessairessiunpointestobscur.Sivousprenezletempsdemenvoyer
lesremarquesetleserreursquevousavezpudtecter,
jevoussauraisgrdevrifieraupralable
quellessonttoujoursdactualitdansladernireversiondecedocument.cettefin,unhistorique
desrvisionsatinclusenpremirepagepourpermettrelidentificationdesdiffrentesditionsde
cedocument.
ii
I.LelangageC++
LeC++estlundeslangagesdeprogrammationlesplusutilissactuellement.Ilestlafoisfacile
utiliseret trsefficace. Il souffrecependant delarputationdtrecompliquet illisible. Cette
rputationestenpartiejustifie.Lacomplexitdulangageestinvitablelorsquonchercheavoir
beaucoupdefonctionnalits.Enrevanche,encequiconcernelalisibilitdesprogrammes,toutdpend
delabonnevolontduprogrammeur.
LescaractristiquesduC++enfontunlangageidalpourcertainstypesdeprojets.Ilestincontour
nabledanslaralisationdesgrandsprogrammes.Lesoptimisationsdescompilateursactuelsenfont
galementunlangagedeprdilectionpourceuxquirecherchentlesperformances.Enfin,celangage
est,avecleC,idalpourceuxquidoiventassurerlaportabilitdeleursprogrammesauniveaudes
fichierssources(pasdesexcutables).
LesprincipauxavantagesduC++sontlessuivants:
grandnombredefonctionnalits;
performancesduC;
facilitdutilisationdeslangagesobjets;
portabilitdesfichierssources;
facilitdeconversiondesprogrammesCenC++,et,enparticulier,possibilitdutilisertoutesles
fonctionnalitsdulangageC;
contrlederreursaccru.
CesderniresnotionssontutilisesintensivementdanslabibliothquestandardC++,aussilalecture
compltedelapremirepartieestelleindispensableavantdesattaquerladeuxime.
Danstoutecettepremirepartie,lasyntaxeseradonne,saufexception,aveclaconventionsuivante:
cequiestentrecrochets( [et ])estfacultatif.Deplus,quandplusieurslmentsdesyntaxesont
sparsparunebarreverticale( |), lundeceslments, etunseulement, doittreprsent(cest
unouexclusif). Enfin, lespointsdesuspensiondsigneront uneitrationventuelledumotif
prcdent.
Parexemple,silasyntaxedunecommandeestlasuivante:
[fac|rty|sss]zer[(kfl[,kfl[...]])];
lescombinaisonssuivantesserontsyntaxiquementcorrectes:
zer;
faczer;
rtyzer;
zer(kfl);
ssszer(kfl,kfl,kfl,kfl);
maislacombinaisonsuivanteseraincorrecte:
facssszer()
pourlesraisonssuivantes:
facetssssontmutuellementexclusifs,bienquefacultatifstouslesdeux;
aumoinsunkflestncessairesilesparenthsessontmises;
ilmanquelepointvirgulefinal.
Chapitre1.PremireapprocheduC/C++
LeC/C++estunlangageprocdural,dummetypequelePascalparexemple.Celasignifiequeles
instructionssontexcuteslinairementetregroupesenblocs:lesfonctionsetlesprocdures(les
procduresnexistentpasenC/C++,cesontdesfonctionsquineretournentpasdevaleur).
Toutprogrammeapourbutdeffectuerdesoprationssurdesdonnes.Lastructurefondamentaleest
donclasuivante:
ENTREDESDONNES
(clavier,souris,fichier,autrespriphriques)
|
TRAITEMENTDESDONNES
|
SORTIEDESDONNES
(cran,imprimante,fichier,autrespriphriques)
Cesdiversestapespeuventtredispersesdansleprogramme.Parexemple,lesentrespeuventse
trouverdansleprogrammemme(lutilisateurnadanscecaspasbesoindelessaisir).Pourlaplupart
desprogrammes,lesdonnesenentreproviennentdufluxdentrestandard,etlesdonnesmises
ensortiesontdirigesverslefluxdesortiestandard.Toutefois,leprocessusdentredesdonnespeut
trerptautantdefoisquencessairependantlexcutiondunprogramme,etlesdonnestraites
aufuretmesurequellesapparaissent.Parexemple,pourlesprogrammesgraphiques,lesdonnes
sontreuesdelapartdusystmesousformedemessagescaractrisantlesvnementsgnrspar
lutilisateurouparlesystmeluimme(dplacementdesouris,fermeturedunefentre,appuisur
unetouche, etc.). Letraitementdesprogrammesgraphiquesestdoncuneboucleinfinie(quelon
appellelaboucledesmessages),quipermetdercuprerlesmessagesetdeprendrelesactionsen
consquence. Danscecas, lasortiedesdonnescorrespondaucomportement queleprogramme
adopteenrponsecesmessages.Celapeuttretoutsimplementdafficherlesdonnessaisies,ou,
plusgnralement,dappliquerunecommandeauxdonnesencoursdemanipulation.
Lesdonnesmanipulessont stockesdansdesvariables, cestdiredeszonesdelammoire.
Commeleurnomlindique,lesvariablespeuventtremodifies(parletraitementdesdonnes).Des
oprationspeuventdonctreeffectuessurlesvariables,maispasnimportelesquelles.Parexemple,
onnepeutpasajouterdespommesdesbananes,saufdfinircetteoprationbienprcisment.Les
oprationsdpendentdoncdelanaturedesvariables.
Afinderduirelesrisquesderreursdepro
grammation,leslangagescommeleC/C++donnentuntypechaquevariable(parexemple:pomme
etbanane).Lorsdelacompilation(phasedetraductiondutextesourceduprogrammeenexcutable),
cestypessontutilisspourvrifiersilesoprationseffectuessontautorises.Leprogrammeurpeut
videmmentdfinirsesproprestypes.
Lelangagefournitdestypesdebaseetdesoprationsprdfiniessurcestypes.Lesoprationsqui
peuvent trefaitessont soit lapplicationdunoprateur, soit lapplicationdunefonctionsurles
variables.Logiquementparlant,ilnyapasdediffrence.Seulelasyntaxechange:
a=2+3
estdoncstrictementquivalent:
a=ajoute(2,3)
Chapitre1.PremireapprocheduC/C++
videmment, desfonctionsutilisateur peuvent tredfinies. Lesoprateursnepeuvent treque
surchargs:ilestimpossibledendfinirdenouveaux(deplus,
lasurchargedesoprateursnest
faisablequenC++). Lanotiondesurchargedefonctionseradcriteendtailcidessous, dansla
Section1.6.4.
Cettepremirepartieest doncconsacreladfinitiondestypes, ladclarationdesvariables, la
constructionetlappeldefonctions,etauxentres/sortiesdebase(fluxdentre/sortiestandards).
1.1.LescommentairesenC++
Lescommentairessontncessairesettrssimplesfaire.Toutprogrammedoittrecomment.At
tentioncependant,tropdecommentairestuelecommentaire,parcequeleschosesimportantessont
noyesdanslesbanalits.
IlexistedeuxtypesdecommentairesenC++:lescommentairesdetypeCetlescommentairesdefin
deligne(quinesontdisponiblesquenC++).
LescommentairesCcommencentaveclasquencebarreobliquetoile.Lescommentairesseter
minentaveclasquenceinverse:unetoilesuiviedunebarreoblique.
Exemple11.CommentaireC
/*
CeciestuncommentaireC
*/
Cescommentairespeuventstendresurplusieurslignes.
Enrevanche,lescommentairesdefindelignessarrtentlafindelalignecourante,etpasavant.
Ilspermettent decommenterplusfacilement lesactionseffectuessurlalignecourante, avant le
commentaire. Lescommentairesdefindelignecommencent parlasquenceconstituededeux
barresobliques(ilsnontpasdesquencedeterminaison,puisquilsneseterminentqulafindela
lignecourante).Parexemple:
Exemple12.CommentaireC++
actionquelconque
actionsuivante
//CeciestuncommentaireC++
1.2.LestypesprdfinisduC/C++
LeC,etencoreplusleC++,estunlangagetyp.Celasignifiequechaqueentitmanipuledansles
programmesdoitdisposerduntypededonnegrceauquellecompilateurpourravrifierlavalidit
desoprationsquonluiappliquera.Lapriseencomptedutypedesdonnespeutapparatrecomme
unecontraintepourleprogrammeur, maisenralitilsagitsurtoutduneaideladtectiondes
erreurs.
Ilexisteplusieurstypesprdfinis.Cesont:
letypevide:void.Cetypeestutilispourspcifierlefaitquilnyapasdetype.Celaauneutilit
pourfairedesprocdures(fonctionsnerenvoyantrien)etlespointeurssurdesdonnesnontypes
(voirplusloin);
Chapitre1.PremireapprocheduC/C++
lescaractres:char;
lescaractreslongs:wchar_t(cenestuntypedebasequepourlelangageC++,maisilestgale
mentdfinidanslabibliothquestandardCetestdoncutilisablemalgrtoutenC);
lesentiers:int;
lesrels:float;
lesrelsendoubleprcision:double;
[et ]).Pourles
lestableauxunedimension,dontlesindicessontspcifispardescrochets(
tableauxdedimensionsuprieureougale2,onutiliseradestableauxdetableaux;
lesstructures,unionsetnumrations(voirplusloin).
Lestypesentiers(int)peuvent trecaractrissdundesmotsclslongoushort.
Cesmotscls
permettentdemodifierlatailledutype, cestdirelaplagedevaleursquilspeuventcouvrir. De
mme, lesrelsendoubleprcisionpeuvent trequalifisdumot cllong, cequi augmenteleur
plagedevaleurs.Onnepeutpasutiliserlemotclshortaveclesdouble.Ondisposedoncdetypes
additionnels:
lesentierslongs:longint,oulong(intestfacultatif);
lesentierscourts:shortint,oushort;
lesrelsenquadrupleprcision:longdouble.
Note:Attention!Ilnyapasdetypedebasepermettantdemanipulerleschanesdecaractres.
EnC/C++,leschanesdecaractressontenralitdestableauxdecaractres.Voustrouverez
plusloinpourdeplusamplesinformationssurleschanesdecaractresetlestableaux.
Latailledestypesnestspcifiedansaucunenorme.Laseulechosequiestindiquedanslanorme
C++,cestquelepluspetittypeestletypechar.Lestaillesdesautrestypessontdoncdesmultiples
decelledutypechar.Deplus,lesingalitssuivantessonttoujoursvrifies:
char shortint int longint
float double longdouble
Chapitre1.PremireapprocheduC/C++
Afindersoudrecesproblmes, laplupart descompilateursbrisent largleselonlaquellele
typeint est letypedesentiersnatifsduprocesseur, et fixent sataille32bitsquellequesoit
larchitectureutilise.Ainsi,letypeshortesttoujourscodsur16bits,letypeintsur32bitsetle
typelongsur32ou64bitsselonquelarchitecturedelamachineest32ou64bits.Autrement
dit,letypequi reprsentelesentiersnativementnestplusletypeint,maisletypelong.Celane
changepaslesprogrammes32bits,puisquecesdeuxtypessontidentiquesdanscecas.Les
programmesdestinsauxmachines64bitspourront quant euxtreoptimissenutilisant le
typelongchaquefoisquelonvoudrautiliserletypededonnesnatifdelamachinecible.Les
programmes16bitsenrevanchentnesontenrevanchepluscompatiblesaveccesrgles,mais
laplupartdescompilateursactuelsnepermettentplusdecompilerdesprogrammes16bitsde
toutesmanires.
Lestypeschar,wchar_tetintpeuventtresignsounon.Unnombresignpeuttrengatif,pasun
nombrenonsign.Lorsquunnombreestsign,lavaleurabsolueduplusgrandnombrereprsentable
estpluspetite.Pardfaut,lesnombresentierssontsigns.Lesignedestypescharetwchar_tdpend
ducompilateurutilis,ilestdoncprfrabledespcifiersystmatiquementsicestypessontsignsou
nonlorsquonlesutiliseentantquetypeentier.Pourprciserquunnombrenestpassign,ilfaut
utiliserlemotclunsigned.Pourprciserquunnombreestsign,onpeututiliserlemotclsigned.
Cesmotsclspeuventtreintervertislibrementaveclesmotsclslongetshortpourlestypesentiers.
Exemple13.Typessignsetnonsigns
unsignedchar
signedchar
unsignedwchar_t
signedwchar_t
unsignedint
signedint
unsignedlongint
longunsignedint
Note:LeC++(etleC++uniquement)considrelestypescharetwchar_tcommelestypesde
basedescaractres.LelangageC++distinguedonclesversionssignesetnonsignesdeces
typesdelaversiondontlesignenestpasspcifi,puisquelescaractresnontpasdenotion
designeassocie.CelasignifiequelescompilateursC++traitentlestypeschar,unsignedchar
etsignedcharcommedestypesdiffrents,etilenestdemmepourlestypeswchar_t,signed
wchar_tetunsignedwchar_t.Cettedistinctionnapaslieudtreauniveaudesplagesdevaleurs
silonconnatlesignedutypeutiliseninternepourreprsenterlestypescharetwchar_t,mais
elleest trsimportantedansladterminationdela signaturedesfonctions, enparticulierau
niveaudumcanismedesurchargedesfonctions.Lesnotionsdesignatureetdesurchargedes
fonctionsserontdtaillesplusloindanscecours.
Lesvaleursaccessiblesaveclesnombressignsnesontpaslesmmesquecellesaccessiblesavecles
nombresnonsigns.Eneffet,unbitestutilispourlesignedanslesnombressigns.Parexemple,si
letypecharestcodsur8bits,onpeutcoderlesnombresallantde0255aveccetypeennonsign
(ilya8chiffresbinaires,chacunpeutvaloir0ou1,onadonc2puissance8combinaisonspossibles,
cequifait256).Ensign,lesvaleursstendentde128127(undeschiffresbinairesestutilispour
lesigne,ilenreste7pourcoderlenombre,doncilreste128possibilitsdanslespositifscommedans
lesngatifs.0estconsidrcommepositif.Entout,ilyaautantdepossibilits.).
Demme,siletypeintestcodsur16bits(casdesmachines16bits),lesvaleursaccessiblesvont
de3276832767oude065535silentiernestpassign.CestlecassurlesPCenmoderel
Chapitre1.PremireapprocheduC/C++
(cestdiresousDOS)etsousWindows3.x.Surlesmachinesfonctionnanten32bits,letypeintest
stocksur32bits:lespacedesvaleursdisponiblesestdonc65536foispluslarge.Cestlecassur
lesPCenmodeprotg32bits(Windows9xouNT,DOSExtender,Linux)etsurlesMacintosh.Sur
lesmachines64bits,letypeintdevraittre64bits(DECAlphaetlaplupartdesmachinesUNIXpar
exemple).
Enfin,letypefloatestgnralementcodsur4octets,etlestypesdoubleetlongdoublesontsouvent
identiquesetcodssur8octets.
Note:Onconstatedoncquelaportabilitdestypesdebaseesttrsalatoire.Celasignifiequil
fautfaireextrmementattentiondanslechoixdestypessilonveutfaireducodeportable(cest
direqui compileraetfonctionnerasansmodificationduprogrammesurtouslesordinateurs).Il
estdanscecasncessairedutiliserdestypesdedonnesquidonnentlesmmesintervallesde
valeurssurtouslesordinateurs.LanormeISOC99imposededfinirdestypesportablesafinde
rglercesproblmessurtouteslesarchitecturesexistantes.Cestypessontdfinisdanslefichier
dentte stdint.h .Il sagitdestypesint8_t,int16_t,int32_tetint64_t,etdeleursversionsnon
signesuint8_t,uint16_t,uint32_tetuint64_t.Latailledecestypesenbitsestindiquedansleur
nometleurutilisationnedevraitpasposerdeproblme.
Delammemanire,deuxreprsentationsdunmmetypepeuventtrediffrentesenmmoire
surdeuxmachinesdarchitecturesdiffrentes,mmetaillegaleennombredebits.Leprob
lmelepluscourantestlordredestockagedesoctetsenmmoirepourlestypesquisontstocks
surplusdunoctet(cestdirequasimenttous).Celaauneimportancecapitalelorsquedesdon
nesdoiventtrechangesentredesmachinesdarchitecturesaprioridiffrentes,parexemple
danslecadredunecommunicationrseau,oulorsdeladfinitiondesformatsdefichiers.Une
solutionsimpleestdetoujoursdchangerlesdonnesauformattexte,oudechoisirunmode
dereprsentationderfrence. Lesbibliothquesrseaudisposent gnralement desmth
odespermettantdeconvertirlesdonnesversunformatcommundchangededonnesparun
rseauetpourrontparexempletreutilises.
1.3.Notationdesvaleurs
Lesentierssenotentdelamaniresuivante:
base10(dcimale):avecleschiffresde09,etlessignes+(facultatif)et.
Exemple14.Notationdesentiersenbase10
12354,2564
Chapitre1.PremireapprocheduC/C++
base8(octale):avecleschiffresde07.Lesnombresoctauxdoiventtreprcdsdun0(qui
indiquelabase).Lesignenepeutpastreutilis.
Exemple16.Notationdesentiersenbase8
01,0154
Lesflottants(pseudorels)senotentdelamaniresuivante:
[signe]chiffres[.[chiffres]][e|E[signe]exposant][f]
o signe indiquelesigne.Onemploielessignes+(facultatif)etaussibienpourlamantisseque
pourlexposant. eou Epermetdedonnerlexposantdunombreflottant.Lexposantestfacultatif.
Sionnedonnepasdexposant, ondoitdonnerdeschiffresderrirelavirguleavecunpointetces
chiffres.Lesuffixe fpermetdeprcisersilenombreestdetypefloatounon(auquelcasilsagit
dundouble).
Leschiffresaprslavirgulesontfacultatifs,maispaslepoint.Sionnemetnilepoint,nilamantisse,
lenombreestunentierdcimal.
Exemple17.Notationdesrels
123.56f,12e12,2
2estentier,2.festrel.
Lescaractressenotententreguillemetssimples:
A,c,(
Bipsonore
Backspace
Dbutdepagesuivante
Retourlaligne(sanssautdeligne)
Passagelaligne
Tabulation
Tabulationverticale
Dautressquencesdchappementsontdisponibles,afindepouvoirreprsenterlescaractresayant
unesignificationparticulireenC:
\\
\"
Lecaractre\
Lecaractre"
Chapitre1.PremireapprocheduC/C++
\
Lecaractre
Lescaractresspciauxpeuventtreutilissdirectementdansleschanesdecaractresconstantes:
"Ceciestunsautdeligne:\nCeciestlalignesuivante."
Siunechanedecaractresconstanteesttroplonguepourtenirsuruneseuleligne,onpeutconcatner
plusieurschanesenlesjuxtaposant:
"Ceciestlapremirechane"
"ceciestladeuxime."
produitlachanedecaractrescompltesuivante:
"Ceciestlapremirechanececiestladeuxime."
Enfin,lesversionslonguesdesdiffrentstypescitsprcdemment(wchar_t,longintetlongdouble)
peuventtrenotesenfaisantprcderousuivrelavaleurdelalettreL.Cettelettredoitprcderla
valeurdanslecasdescaractresetdeschanesdecaractresetlasuivrequandilsagitdesentierset
desflottants.Parexemple:
L"Ceciestunechanedewchar_t."
2.3e5L
1.4.Ladfinitiondesvariables
Lesvariablessimplespeuventtredfiniesaveclasyntaxesuivante:
typeidentificateur;
identificateur est sonnom. Il est possibledecreret
otypeest letypedelavariableet
dinitialiserunesriedevariablesdsleurcrationaveclasyntaxesuivante:
typeidentificateur[=valeur][,identificateur[=valeur][...]];
Chapitre1.PremireapprocheduC/C++
Exemple18.Dfinitiondevariables
inti=0,j=0;
doublesomme;
/*Dfinitetinitialisedeuxentiers0*/
/*Dclareunevariablerelle*/
Lesvariablespeuventtredfiniesquasimentnimporteodansleprogramme.
dfinirunevariabletemporairequelolonenabesoin.
Celapermetdene
Note:Celanestvrai quenC++.EnCpur,onestobligdedfinirlesvariablesaudbutdes
fonctionsoudesinstructionscomposes(voirplusloin).Ilfautdoncconnatrelesvariablestem
porairesncessaireslcrituredumorceaudecodequisuitleurdfinition.
Ladfinitionduntableausefaitenfaisantsuivrelenomdelidentificateurdunepairedecrochets,
contenantlenombredlmentdutableau:
typeidentificateur[taille]([taille](...));
Note:Attention!Lescaractres[et ]tantutilissparlasyntaxedestableaux,ilsnesignifient
plusleslmentsfacultatifsici. Ici,et ici seulement,leslmentsfacultatifssont donnsentre
parenthses.
Danslasyntaxeprcdente,typereprsenteletypedeslmentsdutableau.
Exemple19.Dfinitionduntableau
intMonTableau[100];
MonTableau estuntableaude100entiers.Onrfrenceleslmentsdestableauxendonnantlindice
dellmententrecrochet:
MonTableau[3]=0;
Chapitre1.PremireapprocheduC/C++
Note:Lasyntaxepermettantdinitialiserlestableauxdsleurcrationestunpeupluscomplexe
quecellepermettantdinitialiserlesvariablesdetypesimple.Cettesyntaxeestsemblablecelle
permettantdinitialiserlesstructuresdedonnesetseradoncdcritedanslasectionquileurest
ddie.
EnC/C++,lestableauxplusdunedimensionsontdestableauxdetableaux.Onprendragardeau
faitquedansladfinitionduntableauplusieursdimensions,laderniretailleindiquespcifiela
tailledutableaudontonfaituntableau.Ainsi,danslexemplesuivant:
intMatrice[5][4];
Matrice estuntableaudetaille5dontleslmentssonteuxmmesdestableauxdetaille4.Lordre
dedclarationdesdimensionsestdoncinvers:5estlatailledeladerniredimensionet4estlataille
delapremiredimension.Llmentsuivant:
Matrice[2];
estdoncletroisimelmentdecetableaudetaillecinq,etestluimmeuntableaudequatrel
ments.
EnC/C++,lesindicesdestableauxvarientde 0 taille1.Ilyadoncbientaillelmentsdans
letableau.Danslexempledonncidessus,llment MonTableau[100] nexistepas:yaccder
planteraleprogramme.Cestauprogrammeurdevrifierquesesprogrammesnutilisentjamaisles
tableauxavecdesindicesplusgrandsqueleurtailleoungatifs.
Unautrepointauquelilfaudrafaireattentionestlatailledestableauxutiliserpourleschanesde
caractres.Unechanedecaractressetermineobligatoirementparlecaractrenul(\0),ilfautdonc
rserverdelaplacepourlui.Parexemple,pourcrerunechanedecaractresde100caractresau
plus,ilfautuntableaupour101caractres(dclaravec charchaine[101]; ).
1.5.Instructionsetoprations
Lesinstructionssontgnralementidentifiesparlepointvirgule.Cestcecaractrequimarquela
finduneinstruction.
Exemple110.Instructionvide
;
/*Instructionvide:nefaitrien!*/
Ilexisteplusieurstypesdinstructions,quipermettentderaliserdesoprationsvaries.Lesinstruc
tionslespluscourantessontsansdoutelesinstructionsquieffectuentdesoprations,cestdireles
instructionsquicontiennentdesexpressionsutilisantdesoprateurs.
LesprincipalesoprationsutilisablesenC/C++sontlessuivantes:
lesaffectations:
variable=valeur
Note:Lesaffectationsnesontpasdesinstructions.Cesontbiendes oprationsqui renvoient
la valeur affecte.Onpeutdonceffectuerdesaffectationsmultiples:
Chapitre1.PremireapprocheduC/C++
i=j=k=m=0;
/*Annulelesvariablesi,j,ketm.*/
lesoprationsdebasedulangage:
valeuropvaleur
%reprsentelacongruence(cestdirelerestedeladivisioneuclidienne).|et &reprsentent
respectivementleouetleetbinaire(cestdirebitbit:1et1=1,0etx=0,1oux=1et0ou0
=0). ^reprsenteleouexclusif (1xor1=0,0xor0=0et1xor0=1). ~reprsentelangation
binaire(1devient0etviceversa). <<et >>effectuentundcalagebinaireverslagaucheetla
droiterespectivement,dunnombredebitsgallavaleurdusecondoprande.
lesoprationsdesautresoprateursdulangage.
LeCet leC++disposent doprateursunpeu
plusvolusquelesoprateurspermettantderaliserlesoprationsdebasedulangage.Cesop
rateurssont lesoprateursdincrmentationet dedcrmentation ++ et , loprateurternaire
dvaluationconditionnelleduneexpression(oprateur ?:)etloprateurvirgule(oprateur ,).
Lasyntaxedecesoprateursestdcritecidessous.
lesappelsdefonctions.
suivantes.
Nousverronscommentcrireetappelerdesfonctionsdanslessections
Bienentendu,laplupartdesinstructionscontiendrontdesaffectations.Cesontdoncsansdouteles
affectationsquisontlesplusutilisesparmilesdiversesoprationsralisables,aussileCetleC++
permettentilslutilisationdaffectationscomposes.Uneaffectationcomposeestuneoprationper
mettantderaliserenuneseuletapeuneoprationnormaleetlaffectationdesonrsultatdansla
variableservantdepremieroprande.Lesaffectationscomposesutilisentlasyntaxesuivante:
variableop_affvaleur
o op_aff estlundesoprateurssuivants:+=,=,*=,etc.Cettesyntaxeeststrictementqui
valente:
variable=variableopvaleur
/*Multiplieipar2:i=i*2.*/
Lesoprateursdincrmentationetdedcrmentation ++ et sappliquentcommedesprfixesou
dessuffixessurlesvariables.Lorsquilssontenprfixe,lavariableestincrmenteoudcrmente,
10
Chapitre1.PremireapprocheduC/C++
puissavaleurestrenvoye.Silssontensuffixe,lavaleurdelavariableestrenvoye,puislavariable
estincrmenteoudcrmente.Parexemple:
inti=2,j,k;
j=++i;
k=j++;
/*lafindecetteinstruction,ietjvalent3.*/
/*lafindecetteligne,kvaut3etjvaut4.*/
Note:Onprendragardenutiliserlesoprateursdincrmentationetdedcrmentationpost
fixsquelorsquecelaestrellementncessaire.Eneffet,cesoprateursdoiventcontruireun
objettemporairepourrenvoyerlavaleurdelavariableavantincrmentationoudcrmentation.
Si cetobjettemporairenestpasutilis,il estprfrabledutiliserlesversionsprfixesdeces
oprateurs.
Loprateurternairedvaluationconditionnelle?: estleseuloprateurquidemande3paramtres(
partloprateurfonctionnel () desfonctions,quiadmetnparamtres,etquelondcriraplustard).
Cetoprateurpermetderaliseruntestsuruneconditionetdecalculeruneexpressionouuneautre
selonlersultatdecetest.Lasyntaxedecetoprateurestlasuivante:
test?expression1:expression2
calculeleminimumde i etde j.
Loprateurvirgule,quantlui,permetdvaluerplusieursexpressionssuccessivementetderenvoyer
lavaleurdeladernireexpression.Lasyntaxedecetoprateurestlasuivante:
expression1,expression2[,expression3[...]]
o expression1, expression2,etc.sontlesexpressionsvaluer.Lesexpressionssontvalues
degauchedroite,puisletypeetlavaleurdeladernireexpressionsontutilisspourrenvoyerle
rsultat.Parexemple,lissuedesdeuxlignessuivantes:
doubler=5;
inti=r*3,1;
r vaut5et i vaut1. r*3 estcalculpourrien.
Note:Cesdeuxderniersoprateurspeuventnuiregravementlalisibilitdesprogrammes.Ilest
toujourspossibledercrireleslignesutilisantloprateurternaireavecuntest(voirlaSection
2.1pourlasyntaxedestestsenC/C++).Demme,onpeuttoujoursdcomposeruneexpression
utilisantloprateurvirguleendeuxinstructionsdistinctes.Cedernieroprateurnedevradonc
jamaistreutilis.
11
Chapitre1.PremireapprocheduC/C++
Ilestpossibledecrerdesinstructionscomposes,constituesdinstructionsplussimples.Lesins
tructionscomposesseprsententsouslaformedeblocdinstructionsolesinstructionscontenues
sontencadresdaccoladesouvrantesetfermantes(caractres { et }).
Exemple112.Instructioncompose
{
i=1;
j=i+3*g;
}
Note:Unblocdinstructionsestconsidrcommeuneinstructionunique.Il estdoncinutilede
mettreunpointvirgulepourmarquerlinstruction,puisqueleblocluimmeestuneinstruction.
Enfin,ilexistetoutunjeudinstructionsquipermettentdemodifierlecoursdelexcutiondupro
gramme,commelestests,lesbouclesetlessauts.Cesinstructionsserontdcritesendtaildansle
chapitretraitantdesstructuresdecontrle.
1.6.Lesfonctions
LeC++nepermetdefairequedesfonctions,
pasdeprocdures. Uneprocdurepeuttrefaiteen
utilisantunefonctionnerenvoyantpasdevaleurouenignorantlavaleurretourne.
1.6.1.Dfinitiondesfonctions
Ladfinitiondesfonctionssefaitcommesuit:
typeidentificateur(paramtres)
{
...
/*Instructionsdelafonction.*/
}
Lavaleurdelafonctionrenvoyerestspcifieenutilisantlacommande return,dontlasyntaxe
est:
returnvaleur;
12
Chapitre1.PremireapprocheduC/C++
Exemple113.Dfinitiondefonction
intsomme(inti,intj)
{
returni+j;
}
Siunefonctionnerenvoiepasdevaleur,onluidonneraletypevoid.Siellenattendpasdeparamtres,
salistedeparamtresseravoidounexisterapas. Ilnestpasncessairedemettreuneinstruction
returnlafindunefonctionquinerenvoiepasdevaleur.
Exemple114.Dfinitiondeprocdure
voidrien()
{
return;
}
/*Fonctionnattendantpasdeparamtres*/
/*etnerenvoyantpasdevaleur.*/
/*Cetteligneestfacultative.*/
1.6.2.Appeldesfonctions
Lappeldunefonctionsefaitendonnantsonnom, puislesvaleursdesesparamtresentreparen
thses.Attention!Silnyapasdeparamtres,ilfautquandmmemettrelesparenthses,sinonla
fonctionnestpasappele.
Exemple115.Appeldefonction
inti=somme(2,3);
rien();
Siladclarationcomprenddesvaleurspardfautpourdesparamtres(C++seulement),cesvaleurs
sontutiliseslorsquecesparamtresnesontpasfournislorsdelappel.Siunparamtreestmanquant,
alorstouslesparamtresquilesuiventdoiventeuxaussitreomis.Ilenrsultequeseulslesderniers
paramtresdunefonctionpeuventavoirdesvaleurspardfaut.Parexemple:
inttest(inti=0,intj=2)
{
returni/j;
}
13
Chapitre1.PremireapprocheduC/C++
1.6.3.Dclarationdesfonctions
Toutefonctiondoittredclareavantdtreappelepourlapremirefois.Ladfinitiondunefonc
tionpeutfaireofficededclaration.
Ilpeutsetrouverdessituationsounefonctiondoittreappeledansuneautrefonctiondfinieavant
elle.Commecettefonctionnestpasdfinieaumomentdelappel,elledoittredclare.Demme,
ilestcourantdavoirappelerunefonctiondfiniedansunautrefichierquelefichierdosefait
lappel.Encoreunefois,ilestncessairededclarercesfonctions.
Lerledesdclarationsestdoncdesignalerlexistencedesfonctionsauxcompilateursafindeles
utiliser,toutenreportantleurdfinitionplusloinoudansunautrefichier.
Lasyntaxedeladclarationdunefonctionestlasuivante:
typeidentificateur(paramtres);
otypeest
/*Dclarationdelafonctionminimum*/
/*dfinieplusloin.*/
/*Fonctionprincipale.*/
intmain(void)
{
inti=Min(2,3);
/*AppellafonctionMin,dj
dclare.*/
return0;
}
/*Dfinitiondelafonctionmin.*/
intMin(inti,intj)
{
if(i<j)returni;
elsereturnj;
}
Silondonnedesvaleurspardfautdiffrentesauxparamtresdunefonctiondansplusieursdcla
rationsdiffrentes,lesvaleurspardfaututilisessontcellesdeladclarationvisiblelorsdelappel
delafonction.Siplusieursdclarationssontvisiblesetentrentenconflitauniveaudesvaleurspar
dfautdesparamtresdelafonction,lecompilateurnesaurapasquelledclarationutiliseretsigna
lerauneerreurlacompilation.Enfin,ilestpossibledecomplterlalistedesvaleurspardfautde
ladclarationdunefonctiondanssadfinition.Danscecas,lesvaleurspardfautspcifiesdansla
dfinitionnedoiventpasentrerenconflitaveccellesspcifiesdansladclarationvisibleaumoment
deladfinition,fautedequoilecompilateursignalerauneerreur.
1.6.4.Surchargedesfonctions
IlestinterditenCdedfinirplusieursfonctionsquiportentlemmenom.EnC++,cetteinterdiction
estleve,moyennantquelquesprcautions.Lecompilateurpeutdiffrencierdeuxfonctionsenregar
dantletypedesparamtresquellereoit.Lalistedecestypessappellelasignaturedelafonction.
Enrevanche,letypedursultatdelafonctionnepermetpasdelidentifier,carlersultatpeutnepas
14
Chapitre1.PremireapprocheduC/C++
treutilisoupeuttreconvertienunevaleurdunautretypeavantdtreutilisaprslappeldecette
fonction.
Il est doncpossibledefairedesfonctionsdemmenom(onlesappellealorsdessurcharges)si
et seulement si touteslesfonctionsportant cenompeuvent tredistinguesparleurssignatures.
Lasurchargequiseraappeleseracelledontlasignatureestlaplusprochedesvaleurspassesen
paramtrelorsdelappel.
Exemple117.Surchargedefonctions
floattest(inti,intj)
{
return(float)i+j;
}
floattest(floati,floatj)
{
returni*j;
}
Cesdeuxfonctionsportentlemmenom, etlecompilateurlesaccepteratouteslesdeux.
Lorsde
lappelde test(2,3),ceseralapremirequiseraappele,car2 et 3 sontdesentiers.Lorsdelappel
de test(2.5,3.2),ceseraladeuxime,parceque 2.5 et 3.2 sontrels.Attention!Dansunappel
telque test(2.5,3),leflottant 2.5 seraconvertienentieretlapremirefonctionseraappele.Il
convientdoncdefairetrsattentionauxmcanismesdesurchargedulangage,etdevrifierlesrgles
deprioritutilisesparlecompilateur.
Onveilleranepasutiliserdesfonctionssurchargesdontlesparamtresontdesvaleurspardfaut,
carlecompilateurnepourraitpasfaireladistinctionentrecesfonctions.Dunemaniregnrale,le
compilateurdisposedunensembledergles(dontlaprsentationdpasselecadredecelivre)qui
luipermettentdedterminerlameilleurefonctionappelertantdonnunjeudeparamtres.Si,lors
delarecherchedelafonctionutiliser,lecompilateurtrouvedesambiguts,ilgnreuneerreur.
1.6.5.Fonctionsinline
LeC++disposedumotcl inline,quipermetdemodifierlamthodedimplmentationdesfonc
tions.Placdevantladclarationdunefonction,ilproposeaucompilateurdenepasinstanciercette
fonction.Celasignifiequelondsirequelecompilateurremplacelappeldelafonctionparlecode
correspondant.Silafonctionestgrosseousielleestappelesouvent,leprogrammedevientplusgros,
puisquelafonctionestrcritechaquefoisquelleestappele.Enrevanche,ildevientnettement
plusrapide,puisquelesmcanismesdappeldefonctions,depassagedesparamtresetdelavaleurde
retoursontainsivits.Deplus,lecompilateurpeuteffectuerdesoptimisationsadditionnellesquil
nauraitpaspufairesilafonctionntaitpasinline.Enpratique,onrserveracettetechniquepour
lespetitesfonctionsappelesdansducodedevanttrerapide(lintrieurdesbouclesparexemple),
oupourlesfonctionspermettantdeliredesvaleursdansdesvariables.
Cependant,ilfautsemfier.Lemotcl inline estunindiceindiquantaucompilateurdefairedes
fonctions inline.Ilnyestpasoblig.Lafonctionpeutdonctrsbientreimplmenteclassique
ment. Pire, ellepeuttreimplmentedesdeuxmanires, selonlesmcanismesdoptimisationdu
compilateur.Demme,lecompilateurpeutgalementinlinerlesfonctionsnormalesafindoptimiser
lesperformancesduprogramme.
Deplus,ilfautconnatrelesrestrictionsdesfonctions inline :
15
Chapitre1.PremireapprocheduC/C++
ellesnepeuventpastrercursives;
ellesnesontpasinstancies,donconnepeutpasfairedepointeursurunefonction
inline.
Silunedecesdeuxconditionsnestpasvrifiepourunefonction,lecompilateurlimplmentera
classiquement(elleneseradoncpas inline).
Enfin,dufaitquelesfonctionsinline sontinsrestellesquellesauxendroitsoellessontappeles,
ilestncessairequellessoientcompltementdfiniesavantleurappel.Celasignifieque,contraire
mentauxfonctionsclassiques,ilnestpaspossibledesecontenterdelesdclarerpourlesappeler,
etdefournirleurdfinitiondansunfichierspar. Danscecaseneffet, lecompilateurgnrerait
desrfrencesexternessurcesfonctions,etninsreraitpasleurcode.Cesrfrencesneseraientpas
rsolueslditiondelien, carilnegnregalementpaslesfonctions inline,puisquellessont
supposestreinsressurplacelorsquonlesutilise.Lesnotionsdecompilationdansdesfichiers
sparsetdditiondeliensserontprsentesendtaildansleChapitre6.
Exemple118.Fonctioninline
inlineintMax(inti,intj)
{
if(i>j)
returni;
else
returnj;
}
Pourcetypedefonction,ilesttoutfaitjustifidutiliserlemotcl inline.
1.6.6.Fonctionsstatiques
Pardfaut,lorsquunefonctionestdfiniedansunfichierC/C++,ellepeuttreutilisedanstoutautre
fichierpourvuquellesoitdclareavantsonutilisation.Danscecas,lafonctionestditeexterne.Il
peutcependanttreintressantdedfinirdesfonctionslocalesunfichier,soitafindersoudredes
conflitsdenoms(entredeuxfonctionsdemmenometdemmesignaturemaisdansdeuxfichiers
diffrents),soitparcequelafonctionestuniquementdintrtlocal.LeCetleC++fournissentdonc
lemotcl static qui,unefoisplacdevantladfinitionetlesventuellesdclarationsdunefonc
tion,larenduniqueetutilisableuniquementdanscefichier.partcedtail,lesfonctionsstatiques
sutilisentexactementcommedesfonctionsclassiques.
Exemple119.Fonctionstatique
//Dclarationdefonctionstatique:
staticintlocale1(void);
/*Dfinitiondefonctionstatique:*/
staticintlocale2(inti,floatj)
{
returni*i+j;
}
Lestechniquespermettantdedcouperunprogrammeenplusieursfichierssourcesetdegnrerles
fichiersbinairespartirdecesfichiersserontdcritesdanslechapitretraitantdelamodularitdes
programmes.
16
Chapitre1.PremireapprocheduC/C++
1.6.7.Fonctionsprenantunnombrevariabledeparamtres
Engnral,lesfonctionsontunnombreconstantdeparamtres.Pourlesfonctionsquiontdespara
mtrespardfautenC++,lenombredeparamtrespeutapparatrevariablelappeldelafonction,
maisenralit,lafonctionutilisetoujourslemmenombredeparamtres.
LeCetleC++disposenttoutefoisdunmcanismequipermetauprogrammeurderaliserdesfonc
tionsdontlenombreetletypedesparamtressontvariables.Nousverronsplusloinquelesfonctions
dentre/sortieduCsontdesfonctionsdontlalistedesargumentsnestpasfixe,celaafindepouvoir
raliserunnombrearbitrairedentres/sorties,etcesurnimportequeltypeprdfini.
Engnral,lesfonctionsdontlalistedesparamtresestarbitrairementlonguedisposentduncritre
poursavoirquelestledernierparamtre.Cecritrepeuttrelenombredeparamtres,quipeuttre
fournienpremierparamtrelafonction,ouunevaleurdeparamtreparticulirequidterminelafin
delalisteparexemple.Onpeutaussidfinirlesparamtresquisuiventlepremierparamtrelaide
dunechanedecaractres.
Pourindiqueraucompilateurquunefonctionpeutaccepterunelistedeparamtresvariable,ilfaut
simplementutiliserdespointsdesuspensionsdanslalistedesparamtres:
typeidentificateur(paramtres,...)
danslesdclarationsetladfinitiondelafonction.Danstouslescas,ilestncessairequelafonction
aitaumoinsunparamtreclassique.Lesparamtresclassiquesdoiventimprativementtreavantles
pointsdesuspensions.
Ladifficultapparatenfaitdanslamaniredercuprerlesparamtresdelalistedeparamtresdans
ladfinitiondelafonction.Lesmcanismesdepassagedesparamtrestanttrsdpendantsdela
machine(etducompilateur),unjeudemacrosatdfinidanslefichierdentte stdarg.h pour
faciliterlaccsauxparamtresdelaliste.Pourensavoirplussurlesmacrosetlesfichiersdentte,
consulterleChapitre5.Pourlinstant,sachezseulementquilfautajouterlalignesuivante:
#include <stdarg.h>
17
Chapitre1.PremireapprocheduC/C++
Ilestpossiblederecommencercestapesautantdefoisquelonveut,laseulechosequicompteest
debienfairelinitialisationavec va_start etdebienterminerlaprocdureavec va_end chaque
fois.
Note:Il existeunerestrictionsurlestypesdesparamtresdeslistesvariablesdarguments.
Lorsdelappel desfonctions, uncertainnombredetraitementsalieusurlesparamtres. En
particulier,despromotionsimplicitesont lieu, cequi setraduit parlefait quelesparamtres
rellementpasssauxfonctionsnesontpasdutypedclar.Lecompilateurcontinuedefaireles
vrificationsdetype,maiseninterne,untypeplusgrandpeuttreutilispourpasserlesvaleurs
desparamtres.Enparticulier,lestypescharetshortnesontpasutiliss:lesparamtressont
toujourspromusauxtypeint oulongint. Celaimpliquequelesseulstypesquevouspouvez
utilisersontlestypesciblesdespromotionsetlestypesqui nesontpassujetsauxpromotions
(pointeurs,structuresetunions).Lestypesciblesdanslespromotionssontdterminscomme
suit:
lestypeschar,signedchar,unsignedchar,shortintouunsignedshortintsontpromusenint
Lepremiertype
lesvaleursdeschampsdebitssontconvertiesenintouunsignedintselonlatailleduchamp
debit(voirplusloinpourladfinitiondeschampsdebits);
lesvaleursdetypefloatsontconvertiesendouble.
Exemple120.Fonctionnombredeparamtresvariable
#include <stdarg.h>
/*Fonctioneffectuantlasommede"compte"paramtres:*/
doublesomme(intcompte,...)
{
doubleresultat=0;
/*Variablestockantlasomme.*/
va_listvarg;
/*Variableidentifiantleprochain
paramtre.*/
va_start(varg,compte);/*Initialisationdelaliste.*/
do
/*Parcoursdelaliste.*/
{
resultat=resultat+va_arg(varg,double);
compte=compte1;
}while(compte!=0);
va_end(varg);
/*Terminaison.*/
returnresultat;
}
18
Chapitre1.PremireapprocheduC/C++
1.7.Lafonctionmain
Lorsquunprogrammeestcharg, sonexcutioncommenceparlappeldunefonctionspcialedu
programme.Cettefonctiondoitimprativementsappeler main (principalenanglais)pourque
lecompilateurpuissesavoirquecestcettefonctionquimarqueledbutduprogramme.Lafonction
main estappeleparlesystmedexploitation,ellenepeutpastreappeleparleprogramme,cest
direquellenepeutpastrercursive.
Exemple121.Programmeminimal
intmain()
/*PluspetitprogrammeC/C++.*/
{
return0;
}
1.8.Lesfonctionsdentre/sortiedebase
Nousavonsdistinguaudbutdecechapitrelesprogrammesgraphiques,quitraitentlesvnements
quilsreoivent dusystmesouslaformedemessages, desautresprogrammes, qui reoivent les
donnestraiteretcriventleursrsultatssurlesfluxdentre/sortiestandards.Lesnotionsdeflux
dentre/sortiestandardsnontpastdfiniesplusendtailcemoment,etilesttempsprsent
depalliercettelacune.
1.8.1.Gnralitssurlesfluxdentre/sortieenC
Unfluxestunenotioninformatiquequipermetdereprsenterunflotdedonnessquentiellesen
provenancedunesourcededonnesoudestinationduneautrepartiedusystme.
Lesfluxsont
utilisspouruniformiserlamaniredontlesprogrammestravaillentaveclesdonnes,etdoncpour
simplifierleurprogrammation.Lesfichiersconstituentunbonexempledeflux,maiscenestpasle
seultypedefluxexistant:onpeuttraiterunfluxdedonnesprovenantdunrseau,
duntampon
mmoireoudetouteautresourcededonnesoupartiedusystmepermettantdetraiterlesdonnes
squentiellement.
Surquasimenttouslessystmesdexploitation,lesprogrammesdisposentdsleurlancementdetrois
fluxdentre/sortiestandards.Gnralement,lefluxdentrestandardestassociaufluxdedonnes
provenantdunterminal,etlefluxdesortiestandardlaconsoledeceterminal.Ainsi,lesdonnes
quelutilisateursaisitauclavierpeuventtreluesparlesprogrammessurleurfluxdentrestandard,
19
Chapitre1.PremireapprocheduC/C++
etilspeuventafficherleursrsultatslcranencrivantsimplementsurleurfluxdesortiestandard.
Letroisimefluxstandardestlefluxderreurstandardqui,pardfaut,estgalementassocilcran,
etsurlequelleprogrammepeutcriretouslesmessagesderreurquildsire.
Note:Laplupartdessystmespermettentderedirigerlesfluxstandardsdesprogrammesafin
delesfairetravaillersurdesdonnesprovenantduneautresourcededonnesqueleclavier,
ou, parexemple, deleurfaireenregistrerleursrsultatsdansunfichier. Il est mmecourant
deraliserdespipelinesdeprogrammes,olesrsultatsdelunsontenvoysdansleflux
dentrestandarddelautre,etainsidesuite.Cessuitesdeprogrammessontgalementappels
des tubesenfranais.
Lamanirederaliserlesredirectionsdesfluxstandardsdpenddessystmesdexploitationet
deleursinterfacesutilisateurs.Deplus,lesprogrammesdoiventtrecapablesdetravailleravec
leursfluxdentre/sortiestandardsdemaniregnrique,queceuxcisoientredirigsounon.
Lestechniquesderedirectionneserontdoncpasdcritesplusendtailici.
Vousremarquerezlintrtdavoirdeuxfluxdistinctspourlesrsultatsdesprogrammesetleurs
messagesderreur. Si, lorsduneutilisationnormale, cesdeuxfluxsemlangent lcran, ce
nestpaslecaslorsquelonredirigelefluxdesortiestandard.Seullefluxderreurstandardest
affichlcrandanscecas,etlesmessagesderreurnesemlangentdoncpasauxrsultats
duprogramme.
Onpourrait penser quelesprogrammesgraphiquesnedisposent pasdefluxdentre/ sor
tiestandards.Pourtant,cestgnralementlecas.Lesvnementstraitsparlesprogrammes
graphiquesdansleurboucledemessagesneproviennent gnralement pasdufluxdentre
standard,maisduneautresourcededonnesspcifiquechaquesystme.Enconsquence,
lesprogrammesgraphiquespeuvent toujoursutiliserlesfluxdentre/ sortiestandardsi cela
savrencessaire.
Afindepermettreauxprogrammesdcriresurleursfluxdentre/sortiestandards,labibliothque
Cdfinitplusieursfonctionsextrmementutiles.Lesdeuxprincipalesfonctionssontsansdouteles
fonctions printf et scanf.Lafonction printf (printformattedenanglais)permetdafficher
desdonneslcran,et scanf (scanformatted)permetdeleslirepartirduclavier.
Enralit,cesfonctionsnefontriendautrequedappelerdeuxautresfonctionspermettantdcrire
etdeliredesdonnessurunfichier:lesfonctions fprintf et fscanf. Cesfonctionssutilisent
exactementdelammemanirequelesfonctions printf et scanf,ceciprsquellesprennenten
premierparamtreunestructuredcrivantlefichiersurlequelellestravaillent.Pourlesfluxdentre/
sortiestandards,labibliothqueCdfinitlespseudofichiers stdin, stdout et stderr,quicorres
pondentrespectivementauxfluxdentre,aufluxdesortieetaufluxderreurstandards.Ainsi,tout
appel scanf setraduitparunappel fscanf surlepseudofichier stdin,ettoutappel printf
parunappel fprintf surlepseudofichier stdout.
Note:Il nexistepasdefonctionpermettant dcriredirectement surlefluxderreurstandard.
Parconsquent,poureffectuerdetellescritures,il fautimprativementpasserparlafonction
fprintf,enluifournissantenparamtrelepseudofichierstderr.
LadescriptiondesfonctionsdelabibliothqueCstandarddpassedeloinlecadredececours.
Aussi lesfonctionsdelectureet dcrituresurlesfichiersneserontellespasdcritesplusen
dtail ici.Seuleslesfonctions printf et scanf serontprsentes,carellessontrellementin
dispensablepourlcrituredunprogrammeC.Consultezlabibliographiesivousdsirezobtenir
plusdedtailssurlabibliothqueCetsurtouteslesfonctionsquellecontient.
LeC++disposegalement demcanismesdegestiondesfluxdentre/
sortiequi lui sont
propres.Cesmcanismespermettentdecontrlerplusfinementlestypesdesdonnescrites
etluesdeetpartirdesfluxdentre/sortiestandards.Deplus,ilspermettentderaliserles
oprationsdcritureet delecturedesdonnesformatesdemanirebeaucoupplussimple.
20
Chapitre1.PremireapprocheduC/C++
Cependant, cesmcanismesrequirent desnotionsobjetsavanceset neseront dcritsque
printf
dansleschapitresddisauC++.Commeilestgalementpossibledutiliserlesfonctions
et scanf enC++dunepart,etque,dautrepart,cesfonctionssontessentiellesenC,lasuitede
cettesectionsattacheraleurdescription.Unchapitrecompletestddiauxmcanismesde
gestiondesfluxduC++dansladeuximepartiedecedocument.
1.8.2.Lafonctionprintf
Lafonction printf semploiecommesuit:
printf(chanedeformat[,valeur[,valeur[...]]])
Onpeutpasserautantdevaleursquelonveut, pourpeuquellessoienttoutesrfrencesdansla
chanedeformat.Ellerenvoielenombredecaractresaffichs.
Lachanedeformatpeutcontenirdutexte,maissurtoutelledoitcontenirautantdeformateursque
devariablesafficher.Sicenestpaslecas,leprogrammeplantera.Lesformateurssontplacsdans
letextelolesvaleursdesvariablesdoiventtreaffiches.
Lasyntaxedesformateursestlasuivante:
%[[indicateur]...][largeur][.prcision][taille]type
Unformateurcommencedonctoujoursparlecaractre%.
formateur,ilfautleddoubler(%%).
Pouraffichercecaractresansfaireun
Letypedelavariableafficherestobligatoireluiaussi.Lestypesutilisablessontlessuivants:
Tableau11.Typespourleschanesdeformatdeprintf
Typededonneafficher
Numriques
Caractres
Caractredeformatage
Entierdcimalsign
Entierdcimalnonsign
uoui
Entieroctalnonsign
Entierhexadcimalnonsign
x(aveclescaractresaf)ouX
(aveclescaractresAF)
Flottantsdetypedouble
f,e,g,EouG
Caractreisol
Chanedecaractres
21
Chapitre1.PremireapprocheduC/C++
Typededonneafficher
Pointeurs
Pointeur
Caractredeformatage
p
Note:VoirleChapitre4pourplusdedtailssurlespointeurs.Leformatdespointeursdpend
delamachine.
Lesvaleursflottantesinfiniessontremplacesparlesmentions +INF et INF.Unnonnombre
IEEE(NotANumber)donne +NAN ou NAN.NotezquelestandardCnepermetdeformaterque
desvaleursdetypedouble.Lesvaleursflottantesdetypefloatdevrontdonctreconvertieen
doubleavantaffichage.
Lesautresparamtressontfacultatifs.
Lesvaleursdisponiblespourleparamtredetaillesontlescaractressuivants:
Tableau12.Optionspourlestypesdeschanesdeformat
Option
Typeutilisable
Tailledutype
Pointeur
PointeurFAR(DOSuniquement)
Pointeur
PointeurNEAR(DOSuniquement)
Entier
shortint
Entier,caractreouchane
decaractres
longintouwchar_t
Flottant
longdouble
Exemple122.Utilisationdeprintfetfprintf
#include <stdio.h>
/*Nepascherchercomprendrecetteligne
pourlinstant.Elleestncessairepourutiliser
lesfonctionsprintfetscanf.
*/
intmain(void)
{
inti=2;
printf("Voicilavaleurdei:%d.\n",i);
/*Exempledcrituresurlasortiederreurstandard:*/
fprintf(stderr,"Pasderreurjusquici...\n");
return0;
}
22
Chapitre1.PremireapprocheduC/C++
:justificationgauchedelasortie,avecremplissagedroitepardes0oudesespaces;
+:affichagedusignepourlesnombrespositifs;
espace:lesnombrespositifscommencenttousparunespace.
spcifielaprcisionmaximaledelasortie(nombredechiffres
1.8.3.Lafonctionscanf
Lafonction scanf permetdefaireuneouplusieursentres.Commelafonction printf,elleattend
unechanedeformatenpremierparamtre. Ilfautensuitepasserlesvariablesdevantcontenirles
entresdanslesparamtresquisuivent.Sasyntaxeestlasuivante:
scanf(chanedeformat,&variable[,&variable[...]]);
Ellerenvoielenombredevariableslues.
Necherchezpascomprendrepourlinstantlasignificationdusymbole& setrouvantdevantchacune
desvariables.Sachezseulementquesilestoubli,leprogrammeplantera.
Lachanedeformatpeutcontenirdeschanesdecaractres.Toutefois,siellecontientautrechoseque
desformateurs,letextesaisiparlutilisateurdevracorrespondreimprativementavecleschanesde
caractresindiquesdanslachanedeformat. scanf chercherareconnatreceschanes,etarrtera
lanalyselapremireerreur.
Lasyntaxedesformateurspour scanf diffreunpeudecelledeceuxde
printf :
%[*][largeur][taille]type
23
Chapitre1.PremireapprocheduC/C++
Lafonction scanf nestpastrsadaptelalecturedeschanesdecaractres,caril
nestpas
faciledecontrlerlataillemaximalequelutilisateurpeutsaisir.Cestpourcetteraisonquelon
agnralement recourslafonction fgets, qui permet delireunelignesurlefluxdentre
standardetdestockerlersultatdansunechanedecaractresfournieenpremierparamtre
etdontlalongueurmaximaleestspcifieendeuximeparamtre.Letroisimeparamtrede
lafonction fgets est lefluxpartirduquel lalecturedelalignedoit treralise, cest dire
gnralement stdin.Lanalysedelachanedecaractresainsiluepeutalorstrefaiteavecune
fonctionsimilairelafonction scanf,maisqui litlescaractresanalyserdansunechanede
caractresaulieudelesliredirectement depuislefluxdentrestandard: lafonction sscanf.
Cettefonctionsutiliseexactementcommelafonction scanf,ceci prsquil fautlui fourniren
premierparamtrelachanedecaractresdanslaquellesetrouventlesdonnesinterprter.
Ladescriptiondecesdeuxfonctionsdpasselecadredecedocumentetneseradoncpasfaite
ici.Veuillezvousrfrerladocumentationdevotreenvironnementdedveloppementoula
bibliographiepourplusdedtailsleursujet.
1.9.Exempledeprogrammecomplet
Leprogrammesuivantestdonntitredexemple.Ilcalculelamoyennededeuxnombresentrsau
clavieretlaffiche:
Exemple123.Programmecompletsimple
#include <stdio.h>
/*Autoriselemploideprintfetdescanf.*/
longdoublex,y;
intmain(void)
{
printf("Calculdemoyenne\n");
/*Afficheletitre.*/
printf("Entrezlepremiernombre:");
scanf("%Lf",&x);
/*Entrelepremiernombre.*/
printf("\nEntrezledeuximenombre:");
scanf("%Lf",&y);
/*Entreledeuximenombre.*/
printf("\nLavaleurmoyennede%Lfetde%Lfest%Lf.\n",
x,y,(x+y)/2);
return0;
}
Danscetexemple,leschanesdeformatspcifientdesflottants(f)enquadrupleprcision(L).
24
Chapitre2.Lesstructuresdecontrle
Nousallonsaborderdanscechapitreunautreaspectdulangageindispensablelaprogrammation,
savoir:lesstructuresdecontrle.Cesstructurespermettent,commeleurnomlindique,decontrler
lexcutionduprogrammeenfonctiondecritresparticuliers. LeCetleC++disposentdetoutes
lesstructuresdecontrleclassiquesdeslangagesdeprogrammationcommelestests,lesboucles,les
sauts,etc.Toutescesstructuressontdcritesdanslessectionssuivantes.
2.1.Lastructureconditionnelleif
Lastructureconditionnelle if permetderaliseruntestetdexcuteruneinstructionounonselonle
rsultatdecetest.Sasyntaxeestlasuivante:
if(test)opration;
o test estuneexpressiondontlavaleurestboolenneouentire.Toutevaleurnonnulleestconsi
drecommevraie.Siletestestvrai, opration estexcut.Cepeuttreuneinstructionouunbloc
dinstructions.Unevariantepermetdespcifierlactionexcuterencasdetestfaux:
if(test)opration1;
elseopration2;
Note:Attention!Lesparenthsesautourdutestsontncessaires!
Lesoprateursdecomparaisonsontlessuivants:
Tableau21.Oprateursdecomparaison
==
galit
!=
ingalit
<
infriorit
>
supriorit
<=
infrioritougalit
>=
suprioritougalit
Lesoprateurslogiquesapplicablesauxexpressionsboolennessontlessuivants:
Tableau22.Oprateurslogiques
&&
etlogique
||
oulogique
ngationlogique
25
Chapitre2.Lesstructuresdecontrle
Ilnyapasdoprateurouexclusiflogique.
Exemple21.Testconditionnelif
if(a<b&&a!=0)
{
m=a;
nouveau_m=1;
}
2.2.Labouclefor
Lastructuredecontrle for estsansdoutelunedesplusimportantes.Ellepermetderalisertoutes
sortesdeboucleset,enparticulier,lesbouclesitrantsurlesvaleursdunevariabledecontrle.Sa
syntaxeestlasuivante:
for(initialisation;test;itration)opration;
o initialisation estuneinstruction(ouunblocdinstructions)excuteavantlepremierpar
coursdelaboucledu for. test estuneexpressiondontlavaleurdtermineralafindelaboucle.
itration estloprationeffectuerenfindeboucle,et opration constitueletraitementdela
boucle.Chacunedecespartiesestfacultative.
Lasquencedexcutionestlasuivante:
initialisation
test:sautenfinduforousuite
opration
itration
retourautest
findufor.
Exemple22.Bouclefor
somme=0;
for(i=0;i <=10;i=i+1)somme=somme+i;
Note:EnC++,il estpossiblequelapartieinitialisation dclareunevariable.Danscecas,
for.Parexemple,
lavariabledclarenestdfiniequlintrieurdelinstruction
for(inti=0;i <10;++i);
eststrictementquivalent:
{
inti;
for(i=0;i <10;++i);
}
26
Chapitre2.Lesstructuresdecontrle
Celasignifiequelonnepeut pasutiliserlavariable i aprslinstruction for, puisquellenest
dfiniequedanslecorpsdecetteinstruction.Celapermetderaliserdesvariablesmuettesqui
neserventqulinstructionfor danslaquelleellessontdfinies.
2.3.Lewhile
Le while permetdexcuterdesinstructionsenboucletantquuneconditionestvraie.Sasyntaxeest
lasuivante:
while(test)opration;
Exemple23.Bouclewhile
somme=i=0;
while(somme<1000)
{
somme=somme+2*i/(5+i);
i=i+1;
}
2.4.Ledo
Lastructuredecontrle do permet,toutcommele while,deraliserdesbouclesenattentedune
condition.Cependant,contrairementceluici,ledo effectueletestsurlaconditionaprslexcution
desinstructions.Celasignifiequelesinstructionssonttoujoursexcutesaumoinsunefois,quele
testsoitvrifiounon.Sasyntaxeestlasuivante:
doopration;
while(test);
opration esteffectuejusquceque
test nesoitplusvrifi.
Lordredexcutionest:
27
Chapitre2.Lesstructuresdecontrle
opration
test
Exemple24.Boucledo
p=i=1;
do
{
p=p*i;
i=i+1;
}while(i!=10);
2.5.Lebranchementconditionnel
Danslecasoplusieursinstructionsdiffrentesdoiventtreexcutesselonlavaleurdunevariable
detypeintgral,lcriturede if successifspeuttrerelativementlourde.LeC/C++fournitdoncla
structuredecontrle switch,quipermetderaliserunbranchementconditionnel.Sasyntaxeestla
suivante:
switch(valeur)
{
casecas1:
[instruction;
[break;]
]
casecas2:
[instruction;
[break;]
]
.
.
.
casecasN:
[instruction;
[break;]
]
[default:
[instruction;
[break;]
]
]
}
valeur estvaluenpremier.Sontypedoittreentier.Selonlersultatdelvaluation,lexcution
default est
duprogrammesepoursuitaucasdemmevaleur.Siaucundescasnecorrespondetsi
prsent,lexcutionsepoursuitaprs default.Sienrevanche default nestpasprsent,onsortdu
switch.
28
Chapitre2.Lesstructuresdecontrle
Exemple25.Branchementconditionnelswitch
i=2;
switch(i)
{
case1:
case2:
/*Sii=1ou2,lalignesuivanteseraexcute.*/
i=2i;
break;
case3:
i=0;
/*Cetteligneneserajamaisexcute.*/
default:
break;
}
Note:Ilestinterditdeffectuerunedclarationdevariabledansundescase dun switch.
2.6.Lesaut
LeC/C++disposeduneinstructiondesautpermettantdepoursuivrelexcutionduprogrammeen
unautrepoint. Bienquilsoitfortementdconseilldelutiliser, cetteinstructionestncessaireet
peutparfoistretrsutile,notammentdanslestraitementsderreurs.Sasyntaxeestlasuivante:
gototiquette;
o tiquette estunetiquettemarquantlalignedestinationdanslafonction.Lestiquettessont
simplementdclaresaveclasyntaxesuivante:
tiquette:
Lestiquettespeuventavoirnimportequelnomdidentificateur.
Il nest paspossibledeffectuerdessautsendehorsdunefonction.
Enrevanche, il est possible
deffectuerdessautsendehorset lintrieurdesblocsdinstructionssouscertainesconditions.
Si ladestinationdusaut setrouveaprsunedclaration, cettedclarationnedoit pascomporter
dinitialisations.Deplus,cedoittreladclarationduntypesimple(cestdireunedclarationqui
nedemandepaslexcutiondecode)commelesvariables,lesstructuresoulestableaux.Enfin,si,au
coursdunsaut,lecontrledexcutionsortdelaportedunevariable,celleciestdtruite.
Note:CesderniresrglessontparticulirementimportantesenC++silavariableestunobjet
dont laclasseaunconstructeurouundestructeurnontrivial. VoirleChapitre8pourplusde
dtailscesujet.
AutrerglespcifiqueauC++:ilestimpossibledeffectuerunsautlintrieurdunblocdecode
enexcutionprotge try{}.VoiraussileChapitre9concernantlesexceptions.
29
Chapitre2.Lesstructuresdecontrle
2.7.Lescommandesderupturedesquence
Enplusdu goto vuprcdemment,ilexistedautrescommandesderupturedesquence(cestdire
dechangementdelasuitedesinstructionsexcuter).Cescommandessontlessuivantes:
continue;
ou
break;
ou
return[valeur];
return permetdequitterimmdiatementlafonctionencours.Commeonladjvu,lacommande
return peutprendreenparamtrelavaleurderetourdelafonction.
break permetdepasserlinstructionsuivantlinstruction
brique(cestdirecelledanslaquelleonsetrouve).
continue sautedirectementladernirelignedelinstruction while, do ou for laplusimbrique.
Cetteligneestlaccoladefermante.Cestceniveauquelestestsdecontinuationsontfaitspour for
et do, ouquelesautaudbutdu while esteffectu(suiviimmdiatementdutest).Onrestedonc
danslastructuredanslaquelleonsetrouvaitaumomentdelexcutionde continue,contrairement
cequisepasseavecle break.
Exemple26.Rupturedesquenceparcontinue
/*Calculelasommedes1000premiersentierspairs:*/
somme_pairs=0;
for(i=0;i <1000;i=i+1)
{
if(i%2==1)continue;
somme_pairs=somme_pairs+i;
}
30
Chapitre3.Typesavancsetclassesde
stockage
LelangageC/C++permetladfinitiondetypespersonnalissconstruitspartirdestypesdebase
dulangage.Outrelestableaux,quelonadjprsents,ilestpossiblededfinirdiffrentstypesde
donnesvolus,principalementlaidedelanotiondestructure.Parailleurs,lesvariablesdclares
dansunprogrammesedistinguent,outreparleurtype,parcequelonappelleleurclassedestockage.
Lapremiresectiondecechapitretraiteradoncdelamaniredontonpeutcreretmanipulerde
nouveauxtypesdedonnesenC/C++, etladeuximesectionprsenteralesdiffrentesclassesde
stockageexistantesetleursignificationprcise.
3.1.Structuresdedonnesettypescomplexes
Endehorsdestypesdevariablessimples,leC/C++permetdecrerdestypespluscomplexes.Ces
typescomprennentessentiellementlesstructures,lesunionsetlesnumrations,maisilestgalement
possiblededfinirdenouveauxtypespartirdecestypescomplexes.
3.1.1.Lesstructures
Lestypescomplexespeuvent seconstruirelaidedestructures. Pourcela, onutiliselemot cl
struct.Sasyntaxeestlasuivante:
struct[nom_structure]
{
typechamp;
[typechamp;
[...]]
};
Ilnestpasncessairededonnerunnomlastructure.Lastructurecontientplusieursautresvariables,
appeleschamps.Leurtypeestdonndansladclarationdelastructure.Cetypepeuttrenimporte
quelautretype,mmeunestructure.
Lastructureainsidfiniepeutalorstreutilisepourdfinirunevariabledontletypeestcettestruc
ture.
Pourcela,deuxpossibilits:
fairesuivreladfinitiondelastructureparlidentificateurdelavariable;
Exemple31.Dclarationdevariabledetypestructure
structClient
{
unsignedcharAge;
unsignedcharTaille;
}Jean;
ou,plussimplement:
31
Chapitre3.Typesavancsetclassesdestockage
struct
{
unsignedcharAge;
unsignedcharTaille;
}Jean;
Dansledeuximeexemple,lenomdelastructurenestpasmis.
dclarerlastructureenluidonnantunnom,puisdclarerlesvariablesaveclasyntaxesuivante:
[struct]nom_structureidentificateur;
Exemple32.Dclarationdestructure
structClient
{
unsignedcharAge;
unsignedcharTaille;
};
structClientJean,Philippe;
ClientChristophe;
//ValideenC++maisinvalideenC
32
Chapitre3.Typesavancsetclassesdestockage
Bienquelesdeuxvariablesaientexactementlammestructure,ellessontdetypediffrents!
Eneffet, variable1 estdetypest1,et variable2 detype(lastructurequiapermisdela
construirenapasdenom).Onnepeutdoncpasfairelaffectation.Pourtant,ceprogrammetait
compilableenCpur...
Note:Il estpossibledenepasdonnerdenomunestructurelorsdesadfinitionsanspour
autantdclarerunevariable.Detellesstructuresanonymesnesontutilisablesquedanslecadre
dunestructureinclusedansuneautrestructure:
structstruct_principale
{
struct
{
intchamp1;
};
intchamp2;
};
3.1.2.Lesunions
Lesunionsconstituentunautretypedestructure.Ellessontdclaresaveclemotcl union,quia
lammesyntaxeque struct.Ladiffrenceentrelesstructuresetlesunionsestquelesdiffrents
champsduneunionoccupentlemmeespacemmoire.Onnepeutdonc,toutinstant,nutiliser
quundeschampsdelunion.
Exemple33.Dclarationduneunion
unionentier_ou_reel
{
intentier;
floatreel;
};
unionentier_ou_reelx;
x peutprendrelaspectsoitdunentier,soitdunrel.Parexemple:
x.entier=2;
33
Chapitre3.Typesavancsetclassesdestockage
x.reel=6.546;
/*Discriminantdelvnement.
Permetdechoisircommentlinterprter.*/
union
{
struct
{
intiMouseX;
intiMouseY;
};
struct
{
charcCharacter;
intiShiftState;
};
/*etc.*/
};
/*Structurepermettantdinterprter*/
/*lesvnementssouris.*/
/*Structurepermettantdinterprter*/
/*lesvnementsclavier.*/
};
/*Exempledutilisationdesvnements:*/
intProcessEvent(structSystemEvente)
{
intresult;
switch(e.iEventType)
{
caseMOUSE_EVENT:
/*Traitementdelvnementsouris...*/
result=ProcessMouseEvent(e.iMouseX,e.iMouseY);
break;
caseKEYBOARD_EVENT:
/*Traitementdelvnementclavier...*/
result=ProcessKbdEvent(e.cCharacter,e.iShiftState);
break;
}
returnresult;
}
34
Chapitre3.Typesavancsetclassesdestockage
3.1.3.Lesnumrations
Lesnumrationssontdestypesintgraux(cestdirequilssontbasssurlesentiers),pourlesquels
chaquevaleurdisposedunnomunique.Leurutilisationpermetdedfinirlesconstantesentiresdans
unprogrammeetdelesnommer.Lasyntaxedesnumrationsestlasuivante:
enumenumeration
{
nom1[=valeur1]
[,nom2[=valeur2]
[...]]
};
Danscetexemple, lesnumrsprennentrespectivementleursvaleurs.
dfini,uneresynchronisationalieulorsdeladfinitionde cinq.
3.1.4.Leschampsdebits
Ilestpossiblededfinirdeschampsdebitsetdedonnerdesnomsauxbitsdeceschamps.Pourcela,
onutiliseralemotcl struct etondonneraletypedesgroupesdebits,leursnoms,etenfinleurs
tailles:
Exemple36.Dclarationdunchampsdebits
structchamp_de_bits
{
intvar1;
intbits1a4 :4;
intbits5a10:6;
unsignedintbits11a16:6;
};
/*Dfinitunevariableclassique.*/
/*Premierchamp:4bits.*/
/*Deuximechamp:6bits.*/
/*Dernierchamp:6bits.*/
35
Chapitre3.Typesavancsetclassesdestockage
structchamp_de_bitsessai;
intmain(void)
{
essai.bits1a4=3;
/*suiteduprogramme*/
return0;
}
3.1.5.Initialisationdesstructuresetdestableaux
Lestableauxetlesstructurespeuventtreinitialises,toutcommelestypesclassiquespeuventltre.
Lavaleurservantlinitialisationestdcriteenmettantlesvaleursdesmembresdelastructureoudu
tableauentreaccoladesetenlessparantpardesvirgules:
Exemple37.Initialisationdunestructure
/*DfinitletypeClient:*/
structClient
{
unsignedcharAge;
unsignedcharTaille;
unsignedintComptes[10];
};
/*DclareetinitialiselavariableJohn:*/
structClientJohn={35,190,{13594,45796,0,0,0,0,0,0,0,0}};
Note:LanormeC99fournitgalementuneautresyntaxepluspratiquepourinitialiserlesstruc
tures. Cettesyntaxepermet dinitialiserlesdiffrentschampsdelastructureenlesnommant
explicitement et enleur affectant directement leur valeur. Ainsi, aveccettenouvellesyntaxe,
linitialisationprcdentepeuttreralisedelamaniresuivante:
Exemple38.InitialisationdestructureC99
/*DclareetinitialiselavariableJohn:*/
structClientJohn={
.Taille=190,
.Age=35,
.Comptes[0]=13594,
.Comptes[1]=45796
36
Chapitre3.Typesavancsetclassesdestockage
};
3.1.6.Lesaliasdetypes
LeC/C++disposedunmcanismedecrationdalias,oudesynonymes,destypescomplexes.Le
motclutiliserest typedef.Sasyntaxeestlasuivante:
typedefdfinitionalias;
o alias estlenomquedoitavoirlesynonymedutypeet
tableaux,lasyntaxeestparticulire:
dfinition estsadfinition.Pourles
typedeftype_tableautype[(taille)]([taille](...));
type_tableau estalorsletypedeslmentsdutableau.
Exemple39.Dfinitiondetypesimple
typedefunsignedintmot;
moteststrictementquivalentunsignedint.
Exemple310.Dfinitiondetypetableau
typedefinttab[10];
tabestlesynonymedetableaude10entiers.
Exemple311.Dfinitiondetypestructure
typedefstructclient
{
unsignedintAge;
unsignedintTaille;
}Client;
37
Chapitre3.Typesavancsetclassesdestockage
Client reprsentelastructureclient. Attentionnepasconfondrelenomdelastructure(struct
client)aveclenomdelalias(Client).
Note:Pourcomprendrelasyntaxede typedef,il suffitderaisonnerdelamaniresuivante.Si
londisposeduneexpressionqui permetdedclarerunevariableduntypedonn,alorsilsuffit
deplacerlemotcl typedef devantcetteexpressionpourfaireensortequelidentificateurdela
typedef dans
variabledevienneunidentificateurdetype.Parexemple,sionsupprimelemotcl
ladclarationdutypeClientcidessus,alorsClientdevient unevariabledont letypeest struct
client.
Unefoiscesdfinitionsdaliaseffectues,onpeutlesutilisercommenimportequeltype,puisquils
reprsententdestypes:
unsignedinti=2,j;
/*Dclaredeuxunsignedint*/
tabTableau;
/*Dclareuntableaude10entiers*/
ClientJohn;
/*Dclareunestructureclient*/
John.Age=35;/*InitialiselavariableJohn*/
John.Taille=175;
for(j=0;j <10;j=j+1)Tableau[j]=j; /*InitialiseTableau*/
3.1.7.Transtypages
Ilestparfoisutiledechangerletypedunevaleur.Considronslexemplesuivant:ladivisionde 5 par
2 renvoie 2.Eneffet, 5/2 faitappelladivisioneuclidienne.Commentfairepourobtenirlersultat
avecunnombrerel?Ilfautfaire 5./2,caralors 5. estunnombreflottant.Maisquefairequandon
setrouveavecdesvariablesentires( i et j parexemple)?Lecompilateursignaleuneerreuraprs i
danslexpression i./j !Ilfautchangerletypedelunedesdeuxvariables.Cetteoprationsappelle
letranstypage.Onlaralisesimplementenfaisantprcderlexpressiontranstyperdutypedsir
entourdeparenthses:
(type)expression
Exemple312.TranstypageenC
inti=5,j=2;
((float)i)/j
Danscetexemple, i esttranstypenflottantavantladivision.Onobtientdonc
2.5.
LetranstypageCesttoutpuissantetpeuttrerelativementdangereux.LelangageC++fournitdonc
desoprateursdetranstypagesplusspcifiques,quipermettentparexempledeconserverlaconstance
desvariableslorsdeleurtranstypage.CesoprateursserontdcritsdanslaSection10.2duchapitre
traitantdelidentificationdynamiquedestypes.
38
Chapitre3.Typesavancsetclassesdestockage
3.2.Lesclassesdestockage
LesvariablesC/C++peuventtrecresdediffrentesmanires.Ilestcourant,selonlamaniredont
ellessontcresetlamaniredontellespourronttreutilises,delesclasserendiffrentescatgories
devariables.Lesdiffrentsaspectsquepeuventprendrelesvariablesconstituentcequelonappelle
leurclassedestockage.
Laclassificationlaplussimplequelonpuissefairedesvariablesestlaclassificationlocaleglobale.
Lesvariablesglobalessontdclaresendehorsdetoutblocdinstructions,
danslazonededcla
rationglobaleduprogramme. Lesvariableslocalesenrevanchesontcreslintrieurdunbloc
dinstructions. Lesvariableslocalesetglobalesontdesduresdevie,
desportesetdesemplace
mentsenmmoirediffrents.
Laportedunevariableest lazoneduprogrammedanslaquelleelleest
accessible. Laporte
desvariablesglobalesest tout leprogramme, alorsquelaportedesvariableslocalesest
lebloc
dinstructionsdanslequelellesonttcres.
Laduredeviedunevariableestletempspendantlequelelleexiste.
Lesvariablesglobalessont
cresaudbutduprogrammeetdtruiteslafin,leurduredevieestdonccelleduprogramme.En
gnral,lesvariableslocalesontuneduredeviequivadumomentoellessontdclaresjusqu
lasortiedublocdinstructionsdanslequelellesonttdclares.Cependant,ilestpossibledefaire
ensortequelesvariableslocalessurviventlasortiedeceblocdinstructions.Dautrepart,laporte
dunevariablepeutcommenceravantsaduredeviesicettevariableestdclareaprsledbutdu
blocdinstructionsdanslequelelleestdclare.Laduredevienestdoncpasgalelaportedune
variable.
Laclassedestockagedunevariablepermetdespcifiersaduredevieetsaplaceenmmoire(sa
porteesttoujoursleblocdanslequellavariableestdclare).LeC/C++disposedunventailde
classesdestockageassezlargeetpermetdespcifierletypedevariablequelondsireutiliser:
:laclassedestockagepardfaut.Lesvariablesontpourporteleblocdinstructionsdans
lequelellesonttcres.Ellesnesontaccessiblesquedanscebloc.Leurduredevieestrestreinte
cebloc.Cemotclestfacultatif,laclassedestockage auto tantlaclassepardfaut;
auto
: cetteclassedestockagepermet
decrer desvariablesdont laporteest lebloc
dinstructionsencours, maisqui, contrairement auxvariables auto, nesont pasdtruiteslors
delasortiedecebloc. chaquefoisquelonrentredansceblocdinstructions, lesvariables
statiquesexisteront et auront pourvaleurscellesquellesavaient avant quelonquittecebloc.
Leurduredevieestdonccelleduprogramme,etellesconserventleursvaleurs.Unfichierpeut
treconsidrcommeunbloc.Ainsi,unevariablestatiquedunfichiernepeutpastreaccde
partirdunautrefichier.Celaestutileencompilationspare(voirplusloin);
static
:cetteclassedestockagepermetdecrerunevariabledontlemplacementsetrouve
dansunregistredumicroprocesseur.Ilfautbienconnatrelelangagemachinepourcorrectement
utilisercetteclassedevariable.Enpratique,cetteclasseesttrspeuutilise;
register
volatile :cetteclassedevariablesertlorsdelaprogrammationsystme.Elleindiquequuneva
riablepeuttremodifieenarrireplanparunautreprogramme(parexempleparuneinterruption,
parunthread,parunautreprocessus,parlesystmedexploitationouparunautreprocesseurdans
unemachineparallle).Celancessitedoncderechargercettevariablechaquefoisquonyfait
rfrencedansunregistreduprocesseur,etcemmesiellesetrouvedjdansundecesregistres
(cequipeutarriversionademandaucompilateurdoptimiserleprogramme);
extern :cetteclasseestutilisepoursignalerquelavariablepeuttredfiniedansunautrefichier.
Elleestutilisedanslecadredelacompilationspare(voirleChapitre6pourplusdedtails).
39
Chapitre3.Typesavancsetclassesdestockage
Ilexistegalementdesmodificateurspouvantsappliquerunevariablepourprcisersaconstance:
:cemotclestutilispourrendrelecontenudunevariablenonmodifiable.Enquelque
sorte,lavariabledevientainsiunevariableenlectureseule.Attention,unetellevariablenestpas
forcmentuneconstante:ellepeuttremodifiesoitparlintermdiairedunautreidentificateur,
soitparuneentitextrieureauprogramme(commepourlesvariables volatile).Quandcemot
clestappliquunestructure,aucundeschampsdelastructurenestaccessibleencriture.Bien
quilpuisseparatretrangedevouloirrendreconstanteunevariable,
cemotclaune
utilit.Enparticulier,ilpermetdefaireducodeplussr;
const
mutable :disponibleuniquementenC++,cemotclnesertquepourlesmembresdesstructures.
Ilpermetdepasseroutrelaconstanceventuelledunestructurepourcemembre.Ainsi,unchamp
destructuredclar mutable peuttremodifimmesilastructureestdclare const.
Pourdclareruneclassedestockageparticulire, ilsuffitdefaireprcderousuivreletypedela
variableparlundesmotscls auto, static, register,etc.Onnaledroitdenutiliserqueles
classesdestockagenoncontradictoires.Parexemple, register et extern sontincompatibles,de
mmeque register et volatile,et const et mutable.Parcontre, static et const,demme
que const et volatile,peuventtreutilisessimultanment.
Exemple313.Dclarationdunevariablelocalestatique
intappels(void)
{
staticintn=0;
returnn=n+1;
}
Cettefonctionmmoriselenombredappelsqui
nombre.Enrevanche,lafonctionsuivante:
intappels(void)
{
intn=0;
returnn=n+1;
}
40
Chapitre3.Typesavancsetclassesdestockage
Exemple315.Dclarationdeconstanteexternes
inti=12;
constintj=11;
/*iestaccessibledetouslesfichiers.*/
/*Synonymede"staticconstintj=11;".*/
externconstintk;
constintk=12;
/*Dclaredabordlavariablek...*/
/*puisdonneladfinition.*/
const doiventtreinitialiseslorsdeleur
Notezquetouteslesvariablesdfiniesaveclemotcl
const,ellesdoiventdoncavoir
dfinition.Eneffet,onnepeutpasmodifierlavaleurdesvariables
unevaleurinitiale.Enfin,lesvariablesstatiquesnoninitialisesprennentlavaleurnulle.
/*Illgal:iestdetypeconstint.*/
gnrentuneerreurparcequonnepeutpasaffecterunevaleurdetypeintunevariabledetype
constint.
Enrevanche, pourlestypescomplexes(pointeursetrfrencesenparticulier), lesmcanismesde
vrificationssontplusfins. Nousverronsquelssontlesproblmessoulevsparlemploidesmots
cls const et volatile aveclespointeursetlesrfrencesdanslechapitretraitantdespointeurs.
Enfin, enC++uniquement, lemot cl mutable permet derendreunchampdestructure
accessibleencriture:
const
Exemple316.Utilisationdumotclmutable
structA
{
inti;
mutableintj;
};
//NonmodifiablesiAestconst.
//Toujoursmodifiable.
constAa={1,1};
//ietjvalent1.
intmain(void)
{
a.i=2;
a.j=2;
return0;
}
//ERREUR!aestdetypeconstA!
//Correct:jestmutable.
41
Chapitre3.Typesavancsetclassesdestockage
42
Chapitre4.Lespointeursetrfrences
Lespointeurssont desvariablestrsutilisesenCet enC++. Ilsdoivent treconsidrscomme
desvariables,ilnyariendesorcierderrirelespointeurs.Cependant,lespointeursontundomaine
dapplicationtrsvaste.
Lesrfrencessontdesidentificateurssynonymesdautresidentificateurs,quipermettentdemanipu
lercertainesnotionsintroduitesaveclespointeursplussouplement.EllesnexistentquenC++.
4.1.Notiondadresse
Toutobjetmanipulparlordinateureststockdanssammoire.Onpeutconsidrerquecettem
moireest constituedunesriedecases, casesdanslesquellessont stockeslesvaleursdes
variablesoulesinstructionsduprogramme.Pourpouvoiraccderunobjet(lavaleurdunevariable
oulesinstructionsexcuterparexemple),cestdireaucontenudelacasemmoiredanslaquelle
cet objet est enregistr, il faut connatrelenumrodecettecase. Autrement dit, il faut connatre
lemplacementenmmoiredelobjetmanipuler.Cetemplacementestappelladressedelacase
mmoire,etparextension,ladressedelavariableouladressedelafonctionstockedanscettecase
etcellesquilasuivent.
Toutecasemmoireauneadresseunique. Lorsquonutiliseunevariableouunefonction, lecom
pilateurmanipuleladressedecettedernirepouryaccder.
Cestluiquiconnatcetteadresse, le
programmeurnapassensoucier.
4.2.Notiondepointeur
Uneadresseestunevaleur.Onpeutdoncstockercettevaleurdansunevariable.Lespointeurssont
justementdesvariablesquicontiennentladressedautresobjets,parexempleladresseduneautre
variable.Onditquelepointeurpointesurlavariablepointe.Ici,pointersignifiefairerfrence.
Lesadressessontgnralementdesvaleursconstantes,carengnralunobjetnesedplacepasen
mmoire.Toutefois,lavaleurdunpointeurpeutchanger.Celanesignifiepasquelavariablepointe
estdplaceenmmoire,maispluttquelepointeurpointesurautrechose.
Afindesavoircequiestpointparunpointeur,lespointeursdisposentduntype.Cetypeestconstruit
partirdutypedelobjetpoint.Celapermetaucompilateurdevrifierquelesmanipulationsrali
sesenmmoireparlintermdiairedupointeursontvalides.Letypedespointeurselitpointeurde
...,olespointsdesuspensionreprsententlenomdutypedelobjetpoint.
Lespointeurssedclarentendonnantletypedelobjetquilsdevrontpointer,suivideleuridentifi
cateurprcddunetoile:
int*pi;
//piestunpointeurdentier.
Note:Siplusieurspointeursdoiventtredclars,ltoiledoittrerpte:
int*pi1,*pi2,j,*pi3;
43
Chapitre4.Lespointeursetrfrences
Figure41.Notiondepointeuretdadresse
Ilestpossibledefaireunpointeursurunestructuredansunestructureenindiquantlenomdela
structurecommetypedupointeur:
typedefstructnom
{
structnom*pointeur;
...
}MaStructure;
/*Pointeursurunestructure"nom".*/
4.3.Drfrencement,indirection
Unpointeurneserviraitstrictementriensilnyavaitpasdepossibilitdaccderladressedune
variableoudunefonction(onnepourraitalorspaslinitialiser)ousilnyavaitpasmoyendaccder
lobjetrfrencparlepointeur(lavariablepointenepourraitpastremanipuleoulafonction
pointenepourraitpastreappele).
Cesdeuxoprationssontrespectivementappelesindirectionetdrfrencement.Ilexistedeuxop
rateurspermettantdercuprerladressedunobjetetdaccderlobjetpoint.Cesoprateurssont
respectivement & et *.
Ilesttrsimportantdesassurerquelespointeursquelonmanipulesonttousinitialiss(cest
direcontiennentladressedunobjetvalide,etpasnimportequoi).Eneffet,accderunpointeur
44
Chapitre4.Lespointeursetrfrences
noninitialisrevientlireou,plusgraveencore,criredanslammoireunendroitcompltement
alatoire(selonlavaleurinitialedupointeurlorsdesacration).Engnral,oninitialiselespointeurs
dsleurcration,ou,silsdoiventtreutilissultrieurement,onlesinitialiseaveclepointeurnul.
Celapermettradefaireultrieurementdestestssurlavaliditdupointeurouaumoinsdedtecter
leserreurs.Eneffet,lutilisationdunpointeurinitialisaveclepointeurnulgnresouventunefaute
deprotectionduprogramme,quetoutbondbogueurestcapablededtecter.Lepointeurnulsenote
NULL.
Note: NULL estunemacrodfiniedanslefichierdentte stdlib.h .EnC,ellereprsentela
valeurduneadresseinvalide.Malheureusement,cettevaleurpeutnepastregaleladresse
0 (certainscompilateursutilisentlavaleur1 pour NULL parexemple).Cestpourcelaquecette
macroatdfinie,afindereprsenter,selonlecompilateur,labonnevaleur.VoirleChapitre5
pourplusdedtailssurlesmacrosetsurlesfichiersdentte.
LanormeduC++fixelavaleurnulledespointeurs 0.Parconsquent,lescompilateursC/C++
quidfinissent NULL commetantgal 1 posentunproblmedeportabilitcertain,puisqueun
programmeCqui utilise NULL nestplusvalideenC++.Parailleurs,unmorceaudeprogramme
C++compilableenCquiutiliseraitlavaleur 0 neseraitpascorrectenC.
Il fautdoncfaireunchoix:soitutiliser NULL enCet 0 enC++,soitutiliser NULL partout,quitte
redfinirlamacro NULL pourlesprogrammesC++(solutionquimesemblepluspratique).
Exemple41.Dclarationdepointeurs
inti=0;
int*pi;
pi=&i;
*pi=*pi+1;
/*Dclareunevariableentire.*/
/*Dclareunpointeursurunentier.*/
/*Initialiselepointeuravecladressedecette
variable.*/
/*Effectueuncalculsurlavariablepointeparpi,
cestdiresuriluimme,puisquepicontient
ladressedei.*/
/*cestade,inevautplus0,mais1.*/
Ilestprsentfaciledecomprendrepourquoiilfautrpterltoiledansladclarationdeplusieurs
pointeurs:
int*p1,*p2,*p3;
>,
Exemple42.Utilisationdepointeursdestructures
structClient
{
intAge;
45
Chapitre4.Lespointeursetrfrences
};
Clientstructure1;
Client*pstr=&structure1;
pstr>Age=35;
/*Onauraitpucrire(*pstr).Age=35;*/
4.4.Notionderfrence
Enplusdespointeurs, leC++permetdecrerdesrfrences. Lesrfrencessontdessynonymes
didentificateurs.Ellespermettentdemanipulerunevariablesousunautrenomqueceluisouslaquelle
cettedernireatdclare.
Note:LesrfrencesnexistentquenC++.LeCnepermetpasdecrerdesrfrences.
ref de
Parexemple,si id estlenomdunevariable,ilestpossibledecrerunerfrence
cettevariable.Lesdeuxidentificateurs id et ref reprsententalorslammevariable,etcellecipeut
treaccdeetmodifielaidedecesdeuxidentificateursindistinctement.
Touterfrencedoitserfrerunidentificateur:ilestdoncimpossiblededclarerunerfrence
sanslinitialiser. Deplus, ladclarationdunerfrencenecrepasunnouvelobjetcommecest
lecaspourladclarationdunevariableparexemple. Eneffet, lesrfrencesserapportent des
identificateursdjexistants.
Lasyntaxedeladclarationdunerfrenceestlasuivante:
type&rfrence=identificateur;
//Rfrencesurlavariablei.
//Doublelavaleurdei(etderi).
Ilestpossibledefairedesrfrencessurdesvaleursnumriques.Danscecas,lesrfrencesdoivent
tredclarescommetantconstantes,puisquunevaleurestuneconstante:
constint&ri=3;
int&error=4;
//Rfrencesur3.
//Erreur!Larfrencenestpasconstante.
4.5.Lienentrelespointeursetlesrfrences
Lesrfrencesetlespointeurssonttroitementlis.Eneffet,unevariableetsesdiffrentesrfrences
ontlammeadresse,puisquellespermettentdaccderunmmeobjet.Utiliserunerfrencepour
46
Chapitre4.Lespointeursetrfrences
manipulerunobjetrevientdoncexactementaummequedemanipulerunpointeurconstantconte
nantladressedecetobjet.Lesrfrencespermettentsimplementdobtenirlemmersultatqueles
pointeurs,maisavecuneplusgrandefacilitdcriture.
Cettesimilitudeentrelespointeursetlesrfrencesseretrouveauniveausyntaxique.Parexemple,
considronslemorceaudecodesuivant:
inti=0;
int*pi=&i;
*pi=*pi+1;
//Manipulationdeiviapi.
etfaisonspasserloprateur&deladeuximelignegauchedeloprateurdaffectation:
inti=0;
int&*pi=i;
//Celagnreuneerreurdesyntaxemaisnous
//lignoronspourlesbesoinsdelexplication.
*pi=*pi+1;
Maintenant,comparonsaveclemorceaudecodequivalentsuivant:
inti=0;
int&ri=i;
ri=ri+1;
//Manipulationdeiviari.
4.6.Passagedeparamtresparvariableouparvaleur
Ilyadeuxmthodespourpasserdesvariablesenparamtredansunefonction:lepassageparvaleur
etlepassageparvariable.Cesmthodessontdcritescidessous.
4.6.1.Passageparvaleur
Lavaleurdelexpressionpasseenparamtreestcopiedansunevariablelocale.Cestcettevariable
quiestutilisepourfairelescalculsdanslafonctionappele.
Silexpressionpasseenparamtreestunevariable,soncontenuestcopidanslavariablelocale.
Aucunemodificationdelavariablelocaledanslafonctionappelenemodifielavariablepasseen
paramtre,parcequecesmodificationsnesappliquentquunecopiedecettedernire.
LeCnepermetdefairequedespassagesparvaleur.
47
Chapitre4.Lespointeursetrfrences
Exemple44.Passagedeparamtreparvaleur
voidtest(intj)
/*jestlacopiedelavaleurpasseen
paramtre*/
{
j=3;
/*Modifiej,maispaslavariablefournie
parlappelant.*/
return;
}
intmain(void)
{
inti=2;
test(i);
test(2);
return0;
/*Lecontenudeiestcopidansj.
inestpasmodifi.Ilvauttoujours2.*/
/*Lavaleur2estcopiedansj.*/
4.6.2.Passageparvariable
Ladeuximetechniqueconsistepassernonpluslavaleurdesvariablescommeparamtre,mais
passerlesvariablesellesmmes.Ilnyadoncplusdecopie,plusdevariablelocale.Toutemodifica
tionduparamtredanslafonctionappeleentranelamodificationdelavariablepasseenparamtre.
LeCnepermetpasdefairecetypedepassagedeparamtres(leC++lepermetenrevanche).
Exemple45.PassagedeparamtreparvariableenPascal
Vari:integer;
Proceduretest(Varj:integer)
Begin
{Lavariablejeststrictementgale
lavariablepasseenparamtre.}
j:=2;
{Ici,cettevariableestmodifie.}
End;
Begin
i:=3;
{Initialisei3}
test(i);{Appellelafonction.Lavariableiestpasseen
paramtres,passavaleur.Elleestmodifiepar
lafonctiontest.}
{Ici,ivaut2.}
End.
48
Chapitre4.Lespointeursetrfrences
4.6.3.Avantagesetinconvnientsdesdeuxmthodes
Lespassagesparvariablessontplusrapidesetplusconomesenmmoirequelespassagesparvaleur,
puisquelestapesdelacrationdelavariablelocaleetlacopiedelavaleurnesontpasfaites.
Il
fautdoncviterlespassagesparvaleurdanslescasdappelsrcursifsdefonctionoudefonctions
travaillantavecdesgrandesstructuresdedonnes(matricesparexemple).
Lespassagesparvaleurspermettentdviterdedtruireparmgardelesvariablespassesenpara
mtre. Silonveutseprvenirdeladestructionaccidentelledesparamtrespasssparvariable, il
faututiliserlemotcl const.Lecompilateurinterdiraalorstoutemodificationdelavariabledansla
fonctionappele,cequipeutparfoisobligercettefonctionraliserdescopiesdetravailenlocal.
4.6.4.CommentpasserlesparamtresparvariableenC?
Il nyaquunesolution:
pointeurs.
passerladressedelavariable. Celaconstituedoncuneapplicationdes
VoicicommentlExemple45seraitprogrammenC:
Exemple46.PassagedeparamtreparvariableenC
voidtest(int*pj)
{
*pj=2;
return;
}
/*testattendladressedunentier...*/
/*...pourlemodifier.*/
intmain(void)
{
inti=3;
test(&i);
/*Onpasseladressedeienparamtre.*/
/*Ici,ivaut2.*/
return0;
}
prsent,ilestfaciledecomprendrelasignificationde&danslappelde
entrersontpassesparvariable.
scanf :lesvariables
4.6.5.Passagedeparamtresparrfrence
LasolutionduCestexactementlammequecelleduPascaldupointdevuesmantique.Enfait,
lePascalprocdeexactementdelammemanireeninterne,maislamanipulationdespointeursest
masqueparlelangage.Cependant,plusieursproblmesseposentauniveausyntaxique:
lasyntaxeestlourdedanslafonction,causedelemploideloprateur
* devantlesparamtres;
lasyntaxeestdangereuselorsdelappeldelafonction,puisquilfautsystmatiquementpenser
utiliserloprateur & devantlesparamtres.Unoublidevantunevariabledetypeentieretlavaleur
delentierestutiliselaplacedesonadressedanslafonctionappele(plantageassur,essayez
avec scanf).
49
Chapitre4.Lespointeursetrfrences
LeC++permetdersoudretouscesproblmeslaidedesrfrences.Aulieudepasserlesadresses
desvariables,ilsuffitdepasserlesvariablesellesmmesenutilisantdesparamtressouslaformede
rfrences.Lasyntaxedesparamtresdevientalors:
type&identificateur[,type&identificateur[...]]
Exemple47.PassagedeparamtreparrfrenceenC++
voidtest(int&i)
//iestunerfrenceduparamtreconstant.
{
i=2;
//Modifieleparamtrepassenrfrence.
return;
}
intmain(void)
{
inti=3;
test(i);
//Aprslappeldetest,ivaut2.
//Loprateur&nestpasncessairepourappeler
//test.
return0;
}
Ilestrecommand,pourdesraisonsdeperformances,depasserparrfrencetouslesparamtresdont
lacopiepeutprendrebeaucoupdetemps(enpratique,seulslestypesdebasedulangagepourronttre
passsparvaleur).Bienentendu,ilfaututiliserdesrfrencesconstantesaumaximumafindviter
lesmodificationsaccidentellesdesvariablesdelafonctionappelantedanslafonctionappele.
En
revanche,lesparamtresderetourdesfonctionsnedevrontpastredclarscommedesrfrences
constantes,caronnepourraitpaslescriresictaitlecas.
Exemple48.Passagedeparamtresconstantparrfrence
typedefstruct
{
...
}structure;
voidma_fonction(conststructure&s)
{
...
return;
}
Danscetexemple, s estunerfrencesurunestructureconstante.Lecodesetrouvantlintrieur
delafonctionnepeutdoncpasutiliserlarfrence s pourmodifierlastructure(onnoteracependant
quecestlafonctionellemmequisinterditlcrituredanslavariable s. const estdoncunmot
clcoopratif.Ilnestpaspossibleunprogrammeurdempchersescollguesdcriredansses
variablesaveclemotcl const.NousverronsdansleChapitre8queleC++permetdepallierce
problmegrceunetechniqueappelelencapsulation.).
Unautreavantagedesrfrencesconstantespourlespassagesparvariablesestquesileparamtre
nestpasunevariableou,silnestpasdubontype,unevariablelocaledutypeduparamtreestcre
etinitialiseaveclavaleurduparamtretranstyp.
50
Chapitre4.Lespointeursetrfrences
Exemple49.Crationdunobjettemporairelorsdunpassageparrfrence
voidtest(constint&i)
{
...
//Utilisationdelavariablei
//danslafonctiontest.Lavariable
//iestcresincessaire.
return;
}
intmain(void)
{
test(3);
//Appeldetestavecuneconstante.
return0;
}
Aucoursdecetappel,unevariablelocaleestcre(lavariable
affecte.
4.7.Rfrencesetpointeursconstantsetvolatiles
Lutilisationdesmotscls const et volatile aveclespointeursetlesrfrencesestunpeuplus
compliquequaveclestypessimples.Eneffet,ilestpossiblededclarerdespointeurssurdesva
riables, despointeursconstantssurdesvariables, despointeurssurdesvariablesconstantesetdes
pointeursconstantssurdesvariablesconstantes(bienentendu,ilenestdemmeaveclesrfrences).
Lapositiondesmotscls const et volatile danslesdclarationsdestypescomplexesestdonc
extrmementimportante.Engnral,lesmotscls const et volatile caractrisentcequilespr
cdedansladclaration,silonadoptecommergledetoujourslesplaceraprslestypesdebase.
Parexemple,lexpressionsuivante:
constint*pi;
peuttrercritedelamaniresuivante:
intconst*pi;
51
Chapitre4.Lespointeursetrfrences
parlesprioritsdesoprateurs. Cet ordrepeut tremodifiparlaprsencedeparenthses.
LannexeBdonnelesprioritsdetouslesoprateursduC++.
Ainsi,danslexemplesuivant:
constint*pi[12];
void(*pf)(int*constpi);
LeCetleC++nautorisentquelescrituresquiconserventouaugmententlespropritsdeconstance
etdevolatilit.Parexemple,lecodesuivantestcorrect:
char*pc;
constchar*cpc;
cpc=pc;
/*Lepassagedepccpcaugmentelaconstance.*/
pc,
parcequellesignifiequesilonpeutcriredansunevariableparlintermdiairedupointeur
cpc
pc
onpeutsinterdiredelefaireenutilisant
laplacede
.Enrevanche,silonnapasledroit
dcriredansunevariable,onnepeutenaucuncasseledonner.
Cependant, lesrglesdulangagerelativeslamodificationdesvariablespeuvent
tranges.Parexemple,lelangageinterditunecrituretellequecelleci:
parfoisparatre
char*pc;
constchar**ppc;
ppc=&pc;
/*Interdit!*/
/*Lavariableconstante.*/
/*Pointeurparlintermdiaireduquel
nousallonsmodifierc.*/
/*Interdit,maissupposonsquecenele
soitpas.*/
/*Parfaitementlgal.*/
/*Modifielavariablec.*/
52
Chapitre4.Lespointeursetrfrences
Afindegrercorrectementcettesituation(etlessituationspluscomplexesquiutilisentdestriples
pointeursouencoreplusdindirection),leCetleC++interdisentlaffectationdetoutpointeurdont
lespropritsdeconstanceetdevolatilitsontmoindresquecellesdupointeurcible.Largleexacte
estlasuivante:
1.Onnote cv lesdiffrentesqualificationsdeconstanceetdevolatilitpossibles(savoir: const
volatile, const, volatile ouaucuneclassedestockage).
2.Si lepointeur sourceest unpointeur cvs,0 depointeur cvs,1 depointeur ... depointeur
cvs,n1 detype Tscvs,n,etquelepointeurdestinationestunpointeur cvd,0 depointeur
cvd,1 depointeur...depointeur cvd,n1 detype Tdcvs,n,alorslaffectationdelasource
ladestinationnestlgalequesi:
Cesrglessontsuffisammentcompliquespournepastreapprises.Lescompilateurssechargeront
designalerleserreurssilyenaenpratique.Parexemple:
constcharc=a;
constchar*pc;
constchar**ppc=&pc;
*ppc=&c;
*pc=b;
/*Lgalprsent.*/
/*Illgal(pcachangdetype).*/
Laffectationdedoublepointeurestprsentlgale,parcequelepointeursourceachangdetype
(onnepeutcependanttoujourspasmodifierlecaractre c).
Ilexisteuneexceptionnotablecesrgles:linitialisationdeschanesdecaractres.Leschanesde
caractrestellesque:
"Bonjourtoutlemonde!"
Cependant,ilatoujourstdusagederaliserlinitialisationdeschanesdecaractresdelamanire
suivante:
char*pc="Coucou!";
/*Thoriquementillgal,maistolr
parcompatibilitavecleC.*/
53
Chapitre4.Lespointeursetrfrences
4.8.Arithmtiquedespointeurs
Ilestpossibledeffectuerdesoprationsarithmtiquessurlespointeurs.
Lesseulesoprationsvalidessontlesoprationsexternes(additionetsoustractiondesentiers)etla
soustractiondepointeurs.Ellessontdfiniescommesuit(lasoustractiondunentierestconsidre
commeladditiondunentierngatif):
p+i=adressecontenuedansp+i*taille(lmentpointparp)
et:
p2p1=(adressecontenuedansp2adressecontenuedansp1)/
taille(lmentspointsparp1etp2)
/*Correct*/
/*Peutmarcher,maisparchance.*/
Ilestpossibledeconnatrelatailledunlmentencaractresenutilisantloprateursizeof.Ilala
syntaxedunefonction:
sizeof(type|expression)
Ilattendsoituntype,soituneexpression.Lavaleurretourneestsoitlatailledutypeencaractres,
soitcelledutypedelexpression.Danslecasdestableaux,ilrenvoielatailletotaledutableau.Sison
argumentestuneexpression,cellecinestpasvalue(doncsiilcontientunappelunefonction,
cellecinestpasappele).Parexemple:
54
Chapitre4.Lespointeursetrfrences
sizeof(int)
renvoielatailledunentierencaractres,et:
sizeof(2+3)
4.9.Utilisationdespointeursaveclestableaux
Lestableauxsonttroitementlisauxpointeursparceque,demanireinterne,laccsauxlments
destableauxsefaitparmanipulationdeleuradressedebase, delatailledeslmentsetdeleurs
indices.Enfait,ladressedunimelmentduntableauestcalculeaveclaformule:
Adresse_n=Adresse_Base+n*taille(lment)
4.9.1.Conversionsdestableauxenpointeurs
Afindepouvoirutiliserlarithmtiquedespointeurspourmanipulerleslmentsdestableaux,leC++
effectuelesconversionsimplicitessuivanteslorsquencessaire:
tableauverspointeurdlment;
pointeurdlmentverstableau.
Celapermetdeconsidrerlesexpressionssuivantescommequivalentes:
identificateur[n]
et:
*(identificateur+n)
55
Chapitre4.Lespointeursetrfrences
si identificateur estsoitunidentificateurdetableau,soitceluidunpointeur.
Exemple411.Accsauxlmentsduntableauparpointeurs
inttableau[100];
int*pi=tableau;
tableau[3]=5;
/*Le4melmentestinitialis5*/
*(tableau+2)=4;/*Le3melmentestinitialis4*/
pi[5]=1;
/*Le6melmentestinitialis1*/
Note:LelangageC++imposequeladressesuivantledernierlmentduntableaudoittoujours
trevalide.Celanesignifieabsolumentpasquelazonemmoirerfrenceparcetteadresse
estvalide,bienaucontraire,maispluttquecetteadresseestvalide.Ilestdoncgarantitquecette
adresseneserapaslepointeurNULLparexemple,nitouteautrevaleurspcialequunpointeur
nepeutpasstocker.Il seradoncpossibledefairedescalculsdarithmtiquedespointeursavec
cetteadresse,mmesiellenedevrajamaistredrfrence,souspeinedevoirleprogramme
planter.
Onprendragardecertainessubtilits.Lesconversionsimplicitessontunefacilitintroduitepar
lecompilateur, maisenralit, lestableauxnesont pasdespointeurs, cesont desvariables
commelesautres, ceci prs: leurtypeest convertibleenpointeursurletypedeleursl
ments.Il enrsulteparfoisquelquesambigutslorsquonmanipulelesadressesdestableaux.
Enparticulier,onalgalitsuivante:
&tableau==tableau
enraisondufaitqueladressedutableauestlammequecelledesonpremierlment.Il faut
biencomprendrequedanscetteexpression,uneconversionalieu.Cettegalitnestdoncpas
exacteenthorie.Eneffet,sictaitlecas,onpourraitcrire:
*&tableau==tableau
cequiestfaux(letypedupremierlmentnestengnralpasconvertibleentypepointeur.).
4.9.2.Paramtresdefonctiondetypetableau
Laconsquencelaplusimportantedelaconversiontableauverspointeursetrouvedanslepassagepar
variabledestableauxdansunefonction.Lorsdupassageduntableauenparamtredunefonction,
laconversionimplicitealieu,lestableauxsontdonctoujourspasssparvariable,jamaisparvaleur.
Ilestdoncfauxdutiliserdespointeurspourlespasserenparamtre,carleparamtreauraitletype
pointeurdetableau. Onnemodifierait pasletableau, maisbel et bienlepointeurdutableau. Le
programmeauraitdoncdeforteschancesdeplanter.
Parailleurs,certainescaractristiquesdestableauxpeuventtreutilisespourlespasserenparamtre
danslesfonctions.
Ilestautorisdenepasspcifierlatailledeladerniredimensiondesparamtresdetypetableau
danslesdclarationsetlesdfinitionsdefonctions.Eneffet,labornesuprieuredestableauxnapas
56
Chapitre4.Lespointeursetrfrences
besoindtreprcisepourmanipulerleurslments(onpeutmalgrtoutladonnersicelasemble
ncessaire).
Cependant,pourlesdimensionsdeuxetsuivantes,lestaillesdespremiresdimensionsrestentnces
saires.Siellesntaientpasdonnesexplicitement,lecompilateurnepourraitpasconnatrelerapport
desdimensions.Parexemple,lasyntaxe:
inttableau[][];
utilisepourrfrenceruntableaude12entiersnepermettraitpasdefaireladiffrenceentreles
tableauxdedeuxlignesetdesixcolonnesetlestableauxdetroislignesetdequatrecolonnes(etleurs
transpossrespectifs).Unerfrencetelleque:
tableau[1][3]
/*Passagedutableauenparamtre.*/
4.10.Leschanesdecaractres:pointeursettableaux
lafois!
OnavudanslepremierchapitrequeleschanesdecaractresnexistaientpasenC/C++.Cesonten
ralitdestableauxdecaractresdontlederniercaractreestlecaractrenul.
Celaaplusieursconsquences.Lapremire,cestqueleschanesdecaractressontaussidespoin
teurssurdescaractres,cequisetraduitdanslasyntaxedeladclarationdunechanedecaractres
constante:
constchar*identificateur="chane";
57
Chapitre4.Lespointeursetrfrences
identificateur est dclarici commetant unpointeurdecaractre,
ladressedelachanedecaractresconstante "chane".
nestpaslaffectationducontenudenom2 nom1.Cestuneaffectationdepointeur:lepointeurnom1
estgalaupointeur nom2 etpointentsurlammechane!Unemodificationdelachanepointepar
nom1 entranedonclamodificationdelachanepointepar nom2...
Demme,letest nom1==nom2 estuntestentrepointeurs,pasentrechanesdecaractres.Mmesi
deuxchanessontgales,letestserafauxsiellesnesontpasaummeemplacementmmoire.
IlexistedanslabibliothqueCdenombreusesfonctionspermettantdemanipulerleschanesdeca
ractres.Parexemple,lacopiedunechanedecaractresdansuneautreseferaaveclesfonctions
strcpy et strncpy,lacomparaisondedeuxchanesdecaractrespourratreraliselaidedes
fonctions strcmp et strncmp,etladterminationdelalongueurdunechanedecaractreslaide
delafonction strlen. Jevousinviteconsulterladocumentationdevotreenvironnementded
veloppementoulabibliographiepourdcouvrirtouteslesfonctionsdemanipulationdeschanesde
caractres.Nousenverronsunexempledutilisationdanslasectionsuivante.
4.11.Allocationdynamiquedemmoire
Lespointeurssontsurtoututilisspourcrerunnombrequelconquedevariables,oudesvariablesde
taillequelconque,encoursdexcutionduprogramme.
Entempsnormal,lesvariablessontcresautomatiquementlorsdeleurdfinition.Celaestfaisable
parcequelesvariablescrerainsiqueleurstaillessontconnuesaumomentdelacompilation(cest
lebutdesdclarationsquedindiquerlastructureetlatailledesobjets,etplusgnralementdedonner
lesinformationsncessairesleurutilisation).Parexemple,unelignecomme:
inttableau[10000];
signaleaucompilateurquunevariabletableau de10000entiersdoittrecre.Leprogrammesen
chargeradoncautomatiquementlorsdelexcution.
Maissupposonsqueleprogrammegreunelistedepersonnes.
Onnepeut passavoirlavance
combiendepersonnesserontentres,lecompilateurnepeutdoncpasfairelarservationdelespace
mmoireautomatiquement.Cestauprogrammeurdelefaire.Cetterservationdemmoire(appele
encoreallocation)doittrefaitependantlexcutionduprogramme.Ladiffrenceavecladclaration
detableauprcdente,cestquelenombredepersonnesetdonclaquantitdemmoireallouer,est
variable.Ilfautdoncfairecequonappelleuneallocationdynamiquedemmoire.
4.11.1.AllocationdynamiquedemmoireenC
Il existe deuxprincipales fonctions Cpermettant de demander de la mmoire ausystme
dexploitationetdelaluirestituer.Ellesutilisenttouteslesdeuxlespointeurs,parcequunevariable
allouedynamiquementnapasdidentificateurtantdonnquellentaitaprioripasconnuela
58
Chapitre4.Lespointeursetrfrences
compilation,etnadoncpasputredclare.LespointeursutilissparcesfonctionsCnontpasde
type.Onlesrfrencedoncavecdespointeursnontyps.Leursyntaxeestlasuivante:
malloc(taille)
free(pointeur)
malloc (abrviationdeMemoryALLOCation)allouedelammoire.Elleattendcommepara
mtrelatailledelazonedemmoirealloueretrenvoieunpointeurnontyp(void*).
free (pourFREEmemory)librelammoirealloue.Elleattendcommeparamtrelepointeur
surlazonelibreretnerenvoierien.
Lorsquonalloueunevariabletype,ondoitfaireuntranstypagedupointeurrenvoypar
pointeurdecetypedevariable.
malloc en
/*Autoriselutilisationdeprintf
etdescanf.*/
/*Autoriselutilisationdemalloc
etdefree.*/
/*Autoriselutilisationdestrcpy,
strlenetdestrcmp.*/
/*Typedebasedunlmentdelistedepersonne.*/
typedefstructperson
{
char*name;
/*Nomdelapersonne.*/
char*address;
/*Adressedelapersonne.*/
structperson*next; /*Pointeursurllmentsuivant.*/
}Person;
typedefPerson*People;
/*Typedelistedepersonnes.*/
/*Fonctionsdegestiondeslistesdepersonnes:*/
/*Fonctiondinitialisationdunelistedepersonne.
Lalisteestpasseparvariablepourpermettresoninitialisation.*/
voidinit_list(People*lst)
{
59
Chapitre4.Lespointeursetrfrences
*lst=NULL;
}
/*Fonctiondajoutdunepersonne.Lesparamtresdelapersonne
sontpasssparvariables,maisnepeuventtremodifiscar
ilssontconstants.CesontdeschanesdecaractresC,qui
sontdoncassimilesdespointeursdecaractresconstants.*/
intadd_person(People*lst,constchar*name,constchar*address)
{
/*Creunnouvellment:*/
Person*p=(Person*)malloc(sizeof(Person));
if(p!=NULL)
{
/*Allouelammoirepourlenometladresse.Attention,
ilfautcompterlecaractrenulterminaldeschanes:*/
p>name=(char*)malloc((strlen(name)+1)*sizeof(char));
p>address=(char*)malloc((strlen(address)+1)*sizeof(char));
if(p>name!=NULL&&p>address!=NULL)
{
/*Copielenometladresse:*/
strcpy(p>name,name);
strcpy(p>address,address);
p>next=*lst;
*lst=p;
}
else
{
free(p);
p=NULL;
}
}
return(p!=NULL);
}
/*Fonctiondesuppressiondunepersonne.
Lastructuredelalisteestmodifieparlasuppression
dellmentdecettepersonne.Celapeutimpliquerlamodification
duchanagedellmentprcdent,oulamodificationdelatte
delisteellemme.*/
intremove_person(People*lst,constchar*name)
{
/*Recherchelapersonneetsonantcdant:*/
Person*prev=NULL;
Person*p=*lst;
while(p!=NULL)
{
/*Onsortsillmentcourantestlapersonnerecherche:*/
if(strcmp(p>name,name)==0)
break;
/*Onpassellmentsuivantsinon:*/
prev=p;
p=p >next;
}
if(p!=NULL)
{
/*Lapersonneattrouve,onlasupprimedelaliste:*/
if(prev==NULL)
60
Chapitre4.Lespointeursetrfrences
{
/*Lapersonneestenttedeliste,onmetjour
lepointeurdettedeliste:*/
*lst=p >next;
}
else
{
/*Onmetjourleliendellmentprcdent:*/
prev>next=p>next;
}
/*etonladtruit:*/
free(p>name);
free(p>address);
free(p);
}
return(p!=NULL);
}
/*Simplefonctiondaffichage.*/
voidprint_list(Peopleconst*lst)
{
Personconst*p=*lst;
inti=1;
while(p!=NULL)
{
printf("Personne%d:%s(%s)\n",i,p
p=p >next;
++i;
}
}
>name,p>address);
/*Fonctiondedestructionetdelibrationdelammoire.*/
voiddestroy_list(People*lst)
{
while(*lst!=NULL)
{
Person*p=*lst;
*lst=p >next;
free(p>name);
free(p>address);
free(p);
}
return;
}
intmain(void)
{
intop=0;
size_ts;
charbuffer[16];
charname[256];
/*Creunelistedepersonne:*/
Peoplep;
init_list(&p);
/*Utiliselaliste:*/
do
{
61
Chapitre4.Lespointeursetrfrences
printf("Opration(0=quitter,1=ajouter,2=supprimer)?");
fgets(buffer,16,stdin);
buffer[15]=0;
op=3;
sscanf(buffer,"%d",&op);
switch(op)
{
case0:
break;
case1:
printf("Nom:");
fgets(name,256,stdin);
/*Litlenom.*/
name[255]=0;
/*Assurequelecaractrenul
terminalestcrit.*/
s=strlen(name);
/*Supprimelventuelsautdeligne.*/
if(name[s1]==\n)name[s1]=0;
/*Mmeoprationpourladresse:*/
printf("Adresse:");
fgets(address,256,stdin);
name[255]=0;
s=strlen(address);
if(address[s1]==\n)address[s1]=0;
add_person(&p,name,address);
break;
case2:
printf("Nom:");
fgets(name,256,stdin);
name[255]=0;
s=strlen(name);
if(name[s1]==\n)name[s1]=0;
if(remove_person(&p,name)==0)
{
printf("Personneinconnue.\n");
}
break;
default:
printf("Oprationinvalide\n");
break;
}
if(op!=0)print_list(&p);
}while(op!=0);
/*Dtruitlaliste:*/
destroy_list(&p);
return0;
}
Note: Commevouspouvezleconstater, lalecturedeschanesdecaractressaisiespar
lutilisateur est raliseaumoyendelafonction fgets delabibliothqueCstandard. Cette
fonctionpermet delireunelignecompltesur lefluxspcifientroisimeparamtre, et de
stockerlersultat danslachanedecaractresfournieenpremierparamtre. Ellenelirapas
plusdecaractresquelenombreindiquendeuximeparamtre,cequi permetdecontrlerla
tailledeslignessaisiesparlutilisateur.Lafonctionfgets ncessitemalheureusementquelques
traitementssupplmentairesavantdepouvoirutiliserlachanedecaractreslue,carellencrit
paslecaractrenulterminaldelachaneCsilenombremaximaldecaractreslireestatteint,
et ellestockelecaractredesaut deligneenfindelignesi cenombrenest pasatteint. Il
est doncncessairedesassurer quelaligneseterminebienpar uncaractrenul terminal
dunepart, et desupprimerlecaractredesaut delignesil nest pasessentiel dautrepart.
62
Chapitre4.Lespointeursetrfrences
Cestraitementsconstituent galement unbonexempledemanipulationdespointeurset
chanesdecaractres.
des
Ceprogrammeninterdit paslesdfinitionsmultiplesdepersonnesayant
lemmenom. Il
ninterdit pasnonplusladfinitiondepersonnesanonymes.
Lelecteur pourraessayer de
corrigercespetitsdfautstitredexercice, afindesassurerquelesnotionsdepointeursont
bienassimiles.RappelonsquelespointeurssontunenotionessentielleenCetquil fauttre
doncparfaitementfamiliarisaveceux.
4.11.2.AllocationdynamiqueenC++
Enplusdesfonctions malloc et free duC,leC++fournitdautresmoyenspouralloueretrestituer
lammoire.Pourcela,ildisposedoprateursspcifiques: new, delete, new[] et delete[].La
syntaxedecesoprateursestrespectivementlasuivante:
newtype
deletepointeur
newtype[taille]
delete[]pointeur
//quivalent(int*)malloc(sizeof(int)).
//quivalentfree(pi);
etdtruirecetableaudelamaniresuivante:
delete[]Tableau;
63
Chapitre4.Lespointeursetrfrences
Loprateur new[] permetgalementdallouerdestableauxplusieursdimensions.Pourcela,ilsuffit
despcifierlestaillesdesdiffrentesdimensionslasuitedutypededonnedeslementsdutableau,
exactementcommelorsqueloncreuntableaustatiquement.Toutefois,seulelapremiredimension
dutableaupeut trevariable, et lesdimensionsdeuxet suivantesdoivent avoirunetailleentire
positiveetconstante.Parexemple,seuleladeuximelignedelexemplequisuitestuneallocation
dynamiquedetableauvalide:
inti=5,j=3;
int(*pi1)[3]=newint[i][3];//Alloueuntableaudeilignesdetroisentiers.
int(*pi2)[3]=newint[i][j];//Illgal,jnestpasconstant.
Silondsirerellementavoirdestableauxdontplusieursdimensionssontdetaillevariable,ondevra
alloueruntableaudepointeurset,pourchaquelignedecetableau,allouerunautretableaulamain.
Note:Ilestimportantdutiliserloprateurdelete[] aveclespointeursrenvoysparloprateur
new[] et loprateur delete aveclespointeursrenvoyspar new. Deplus, onnedevrapas
nonplusmlangerlesmcanismesdallocationmmoireduCet duC++(utiliser delete sur
unpointeurrenvoypar malloc parexemple).Eneffet,lecompilateurpeutallouerunequantit
demmoiresuprieurecelledemandeparleprogrammeafindestockerdesdonnesqui
lui permettentdegrerlammoire. Cesdonnespeuvent treinterprtesdiffremment pour
chacunedesmthodesdallocation,sibienquuneutilisationerronepeutentranersoitlaperte
desblocsdemmoire,soituneerreur,soitunplantage.
64
Chapitre4.Lespointeursetrfrences
Loprateur new estdoncsusceptibledelanceruneexception std::bad_alloc.VoirleChapitre9
pourplusdedtailscesujet.
Ilestpossiblederemplacerlegestionnairederreurappelparloprateur new laidedelafonction
std::set_new_handler,dclaredanslefichierdenttenew.Cettefonctionattendenparamtre
unpointeursurunefonctionquineprendaucunparamtreetnerenvoierien.Ellerenvoieladresse
dugestionnairederreurprcdent.
Note:Lafonction std::set_new_handler et laclassestd::bad_allocfont partiedelabiblio
thquestandardC++. Commeleursnomslindiquent, ilssont dclarsdanslespacedenom
mage std::,quiestrservpourlesfonctionsetlesclassesdelabibliothquestandard.Voyez
aussi leChapitre11pourplusdedtailssurlesespacesdenommages.Sivousnedsirezpas
new.h
utiliserlesmcanismesdesespacesdenommage,vousdevrezinclurelefichierdentte
aulieude new.
Attendezvouscequunjour, touslescompilateursC++lancent uneexceptionencasde
manquedemmoirelorsdelappel loprateur new,carcestcequimposelanorme.Si vous
nedsirezpasavoirgrerlesexceptionsdansvotreprogrammeet
continuerrecevoirun
pointeurnulencasdemanquedemmoire,vouspouvezfournirundeuximeparamtredetype
std::nothrow_tloprateur new.Labibliothquestandarddfinitlobjetconstant std::nothrow
cetusage.
4.12.Pointeursetrfrencesdefonctions
4.12.1.Pointeursdefonctions
Il est possibledefairedespointeursdefonctions. Unpointeurdefonctioncontient ladressedu
dbutducodebinaireconstituantlafonction.Ilestpossibledappelerunefonctiondontladresseest
contenuedansunpointeurdefonctionavecloprateurdindirection*.
Pourdclarerunpointeurdefonction,ilsuffitdeconsidrerlesfonctionscommedesvariables.Leur
dclarationestidentiquecelledestableaux,enremplaantlescrochetspardesparenthses:
type(*identificateur)(paramtres);
/*Dclareunpointeurdefonction.*/
pf estunpointeurdefonctionattendantcommeparamtresdeuxentiersetrenvoyantunentier.
65
Chapitre4.Lespointeursetrfrences
typedefint(*PtrFonct)(int,int);
PtrFonctpf;
PtrFonct estletypedespointeursdefonctions.
/*Autoriselemploidescanfetdeprintf.*/
intf(inti,intj)
{
returni+j;
}
/*Dfinitunefonction.*/
int(*pf)(int,int);
/*Dclareunpointeurdefonction.*/
intmain(void)
{
intl,m;
/*Dclaredeuxentiers.*/
pf=&f;
/*Initialisepfavecladressedelafonctionf.*/
printf("Entrezlepremierentier:");
scanf("%u",&l);
/*Initialiselesdeuxentiers.*/
printf("\nEntrezledeuximeentier:");
scanf("%u",&m);
/*Utiliselepointeurpfpourappelerlafonctionf
etaffichelersultat:*/
printf("\nLeursommeestde:%u\n",(*pf)(l,m));
return0;
}
Lintrtdespointeursdefonctionestdepermettrelappeldunefonctionparmiunventaildefonc
tionsauchoix.
Parexemple,ilestpossibledefaireuntableaudepointeursdefonctionsetdappelerlafonctiondont
onconnatlindicedesonpointeurdansletableau.
Exemple416.Applicationdespointeursdefonctions
#include <stdio.h>
/*Autoriselemploidescanfetdeprintf.*/
/*Dfinitplusieursfonctionstravaillantsurdesentiers:*/
intsomme(inti,intj)
{
returni+j;
}
intmultiplication(inti,intj)
{
returni*j;
}
66
Chapitre4.Lespointeursetrfrences
intquotient(inti,intj)
{
returni/j;
}
intmodulo(inti,intj)
{
returni%j;
}
typedefint(*fptr)(int,int);
fptrftab[4];
intmain(void)
{
inti,j,n;
ftab[0]=&somme;
/*Initialiseletableaudepointeur*/
ftab[1]=&multiplication;/*defonctions.*/
ftab[2]="ient;
ftab[3]=&modulo;
printf("Entrezlepremierentier:");
scanf("%u",&i);
/*Demandelesdeuxentiersietj.*/
printf("\nEntrezledeuximeentier:");
scanf("%u",&j);
printf("\nEntrezlafonction:");
scanf("%u",&n);
/*Demandelafonctionappeler.*/
if(n < 4)
printf("\nRsultat:%u.\n",(*(ftab[n]))(i,j));
else
printf("\nMauvaisnumrodefonction.\n");
return0;
}
4.12.2.Rfrencesdefonctions
Lesrfrencesdefonctionssont acceptesenC++. Cependant, leurusageest assezlimit. Elles
permettentparfoisdesimplifierlescrituresdanslesmanipulationsdepointeursdefonctions.Mais
commeilnestpaspossiblededfinirdestableauxderfrences, leprogrammedexempledonn
cidessusnepeutpastrercritavecdesrfrences.
Lesrfrencesdefonctionspeuventmalgrtouttreutilisesprofitdanslepassagedesfonctions
enparamtredansuneautrefonction.Parexemple:
#include <stdio.h>
//Autoriselemploidescanfetdeprintf.
//Fonctiondecomparaisondedeuxentiers:
intcompare(inti,intj)
{
if(i<j)return1;
elseif(i>j)return1;
elsereturn0;
}
67
Chapitre4.Lespointeursetrfrences
//Fonctionutilisantunefonctionentantqueparamtre:
voidtrie(inttableau[],inttaille,int(&fcomp)(int,int))
{
//Effectueletridetableauaveclafonctionfcomp.
//Cettefonctionpeuttreappelecommetoutelesautres
//fonctions:
printf("%d",fcomp(2,3));
.
.
.
return;
}
intmain(void)
{
intt[3]={1,5,2};
trie(t,3,compare);
return0;
}
//Passagedecompare()enparamtre.
4.13.Paramtresdelafonctionmainlignede
commande
Lappeldunprogrammesefaitnormalementaveclasyntaxesuivante:
nomparam1param2[...]
Lesparamtresdelalignedecommandespeuventtrercuprsparlafonctionmain.Sivousdsirez
lesrcuprer,lafonction main doitattendredeuxparamtres:
lepremierestunentier,quireprsentelenombredeparamtres;
ledeuximeestuntableaudechanesdecaractres(doncenfaituntableaudepointeurs,ouencore
unpointeurdepointeursdecaractres).
Lesparamtressercuprentaveccetableau.Lepremierlmentpointetoujourssurlachanedon
nantlenomduprogramme.Lesautreslmentspointentsurlesparamtresdelalignedecommande.
68
Chapitre4.Lespointeursetrfrences
Exemple417.Rcuprationdelalignedecommande
#include <stdio.h>
/*Autoriselutilisationdesfonctions*/
/*printfetscanf.*/
intmain(intn,char*params[]) /*Fonctionprincipale.*/
{
inti;
/*Affichelenomduprogramme:*/
printf("Nomduprogramme:%s.\n",params[0]);
/*Affichelalignedecommande:*/
for(i=1;i <n;++i)
printf("Argument%d:%s.\n",i,params[i]);
return0;
/*Toutsestbienpass:onrenvoie0!*/
}
4.14.DANGER
Lespointeurssont,commeonlavu,trsutilissenC/C++.Ilfautdoncbiensavoirlesmanipuler.
Maisilssonttrsdangereux,carilspermettentdaccdernimportequellezonemmoire,silsne
sontpascorrectementinitialiss.Danscecas,ilspointentnimporteo.Accderlammoireavec
unpointeurnoninitialispeutaltrersoitlesdonnesduprogramme,
soitlecodeduprogramme
luimme,soitlecodedunautreprogrammeouceluidusystmedexploitation.Celaconduitdans
lamajoritdescasauplantageduprogramme,etparfoisauplantagedelordinateursilesystmene
disposepasdemcanismesdeprotectionefficaces.
VEILLEZTOUJOURSINITIALISERLESPOINTEURSQUEVOUS
UTILISEZ.
Pourinitialiserunpointeurquinepointesurrien(cestlecaslorsquelavariablepointenestpas
encorecreoulorsquelleestinconnuelorsdeladclarationdupointeur),onutiliseralepointeur
prdfini NULL.
VRIFIEZQUETOUTEDEMANDEDALLOCATIONMMOIREAT
SATISFAITE.
69
Chapitre4.Lespointeursetrfrences
Danstouslescas,
LORSQUONUTILISEUNPOINTEUR,ILFAUTVRIFIERSILESTVALIDE
70
Chapitre5.LeprprocesseurC
5.1.Dfinition
Leprprocesseurestunprogrammequianalyseunfichiertexteetquiluifaitsubircertainestransfor
mations.Cestransformationspeuventtrelinclusiondunfichier,lasuppressiondunezonedetexte
ouleremplacementdunezonedetexte.
Leprprocesseur effectuecesoprationsensuivant
danalyse.
5.2.Lescommandesduprprocesseur
Touteslescommandesduprprocesseurcommencent:
endbutdeligne;
parunsignedise( #).
Lescommandessontlessuivantes:
5.2.1.Inclusiondefichier
Linclusiondefichierpermetdefactoriserdutextecommunplusieursautresfichiers(parexemple
desdclarationsdetype,deconstante,defonction,etc.).Letextecommunestmisengnraldansun
fichierportantlextension .h (pourheader,fichierdenttedeprogramme).
Syntaxe:
#include"fichier"
ou:
#include <fichier>
fichier estlenomdufichierinclure.Lorsquesonnomestentreguillemets,lefichierspcifiest
recherchdanslerpertoirecourant(normalementlerpertoireduprogramme).Silestencadrde
crochets,ilestrecherchdaborddanslesrpertoiresspcifisenlignedecommandeavecloption
I,puisdanslesrpertoiresducheminderecherchedesenttesdusystme(cesrglesnesontpas
fixes,ellesnesontpasnormalises).
Lefichierinclusesttraitluiaussiparleprprocesseur.
Lasignificationdelaligne #include <stdio.h> audbutdetouslesprogrammesutilisantles
fonctions scanf et printf devientalorsclaire.Sivousouvrezlefichier stdio.h,vousyverrezla
dclarationdetouteslesfonctionsetdetouslestypesdelabibliothquedentresortiestandard.De
71
Chapitre5.LeprprocesseurC
mme,lesfonctions malloc et free sontdclaresdanslefichierdentte stdlib.h etdfinies
danslabibliothquestandard.Linclusiondecesfichierspermetdoncdedclarercesfonctionsafin
delesutiliser.
5.2.2.Constantesdecompilationetremplacementdetexte
Leprprocesseurpermetdedfinirdesidentificateursqui,utilissdansleprogramme,serontrempla
cstextuellementparleurvaleur.Ladfinitiondecesidentificateurssuitlasyntaxesuivante:
#defineidentificateurtexte
Leprprocesseurdfinituncertainnombredeconstantesdecompilationautomatiquement.Cesont
lessuivantes:
__LINE__ :donnelenumrodelalignecourante;
__FILE__ :donnelenomdufichiercourant;
72
Chapitre5.LeprprocesseurC
__DATE__ :renvoieladatedutraitementdufichierparleprprocesseur;
__TIME__ :renvoielheuredutraitementdufichierparleprprocesseur;
: dfinieuniquement danslecasdunecompilationC++.
Savaleur doit tre
denormedu2dcembre1996. En
pratique, savaleur est dpendantedelimplmentationutilise, maisonpourrautiliser cette
chanederemplacementpourdistinguerlespartiesdecodecritesenC++decellescritesenC.
__cplusplus
199711L pourlescompilateurscompatiblesavecleprojet
5.2.3.Compilationconditionnelle
Ladfinitiondesidentificateursetdesconstantesdecompilationesttrsutilisepoureffectuerce
quelonappellelacompilationconditionnelle. Lacompilationconditionnelleconsisteremplacer
certainesportionsdecodesourcepardautres,enfonctiondelaprsenceoudelavaleurdeconstantes
decompilation.Celaestralisablelaidedesdirectivesdecompilationconditionnelle,dontlaplus
couranteestsansdoute #ifdef :
#ifdefidentificateur
.
.
.
#endif
(ifnotdefined...)
(sinon,si...)
(si...)
permetdinclureunmorceaudecodeC++strictementconformelanormedcritedansleprojetde
normedu2dcembre1996.
Uneautreapplicationcourantedesdirectivesdecompilationestlaprotectiondesfichiersdentte
contrelesinclusionsmultiples:
73
Chapitre5.LeprprocesseurC
#ifndefDejaLa
#defineDejaLa
Texteninclurequuneseulefoisauplus.
#endif
Celapermetdviterqueletextesoitinclusplusieursfois,lasuitedeplusieursappelsde #include.
Eneffet,aupremierappel, DejaLa nestpasconnuduprprocesseur.Ilestdoncdclaretletexte
estinclus. Lorsdetoutautreappelultrieur, DejaLa existe, etletextenestpasinclus. Cegenre
dcritureserencontredanslesfichiersdentte, pourlesquelsengnral onneveut pasquune
inclusionmultipleaitlieu.
5.2.4.Autrescommandes
Leprprocesseurestcapabledeffectuerdautresactionsquelinclusionetlasuppressiondetexte.
Lesdirectivesquipermettentdeffectuercesactionssontindiquescidessous:
#
:nefaitrien(directivenulle);
#errormessage
:permetdestopperlacompilationenaffichantlemessagederreurdonnen
paramtre;
#linenumro[fichier]:permetdechangerlenumrodelignecourantetlenomdufichier
courantlorsdelacompilation;
#pragmatexte :permetdedonnerdesordresspcifiquesunelimplmentationducompilateur
toutenconservantlaportabilitduprogramme.Touteimplmentationquinereconnatpasunordre
donndansunedirective #pragma doitlignorerpourviterdesmessagesderreurs.Leformatdes
ordresquelonpeutspcifierlaidedeladirective #pragma nestpasnormalisetdpendde
chaquecompilateur.
5.3.Lesmacros
Leprprocesseurpeut,lorsdumcanismederemplacementdetexte,utiliserdesparamtresfournis
lidentificateurremplacer.Cesparamtressontalorsreplacssansmodificationdansletextede
remplacement.Letextederemplacementestalorsappelmacro.
Lasyntaxedesmacrosestlasuivante:
#definemacro(paramtre[,paramtre[...]])dfinition
Exemple52.MacrosMINetMAX
#defineMAX(x,y)((x)>(y)?(x):(y))
#defineMIN(x,y)((x)<(y)?(x):(y))
74
Chapitre5.LeprprocesseurC
Note:Pourpoursuivreunedfinitionsurlalignesuivante,terminezlalignecouranteparlesigne
\.
Lemcanismedesmacrospermetdefairelquivalentdefonctionsgnrales,quifonctionnentpour
touslestypes.Ainsi,lamacro MAX renvoielemaximumdesesdeuxparamtres,quilssoiententiers,
longsourels. Cependant, onprendragardeaufait quelesparamtrespasssunemacrosont
valusparcellecichaquefoisquilssontutilissdansladfinitiondelamacro.Celapeutposer
desproblmesdeperformancesou, pire, provoquerdeseffetsdebordsindsirables. Parexemple,
lutilisationsuivantedelamacro MIN :
MIN(f(3),5)
provoqueleremplacementsuivant:
((f(3))<(5))?(f(3)):(5))
sontdoncprohiber.
Onmettratoujoursdesparenthsesautourdesparamtresdelamacro.
Eneffet, cesparamtres
peuventtredesexpressionscomposes, quidoiventtrecalculescompltementavantdtreuti
lisesdanslamacro.Lesparenthsesforcentcecalcul.Sionnelesmetpas,lesrglesdepriorits
peuventgnreruneerreurdelogiquedanslamacroellemme.Demme,onentoureradeparen
thseslesmacrosrenvoyantunevaleur,afindeforcerleurvaluationcomplteavanttouteutilisation
dansuneautreexpression.Parexemple:
#definemul(x,y)x*y
estunemacrofausse.Laligne:
mul(2+3,5+9)
seraremplacepar:
2+3*5+9
carelledonneletextesuivant:
((2+3)*(5+9))
etlersultatestcorrect.Demme,lamacro:
75
Chapitre5.LeprprocesseurC
#defineadd(x,y)(x)+(y)
estfausse,carlexpressionsuivante:
add(2,3)*5
estremplacetextuellementpar:
(2)+(3)*5
Ainsi,lesparenthsesassurentuncomportementcohrentdelamacro.Commeonlevoit,lesparen
thsespeuventalourdirlesdfinitionsdesmacros,maisellessontabsolumentncessaires.
Lersultatduremplacementdunemacroparsadfinitionest,
luiaussi, soumisauprprocesseur.
Parconsquent, unemacropeut utiliseruneautremacroouuneconstantedfinieavec #define.
Cependant,cemcanismeestlimitauxmacrosquinontpasencoretremplacesafindviterune
rcursioninfinieduprprocesseur.Parexemple:
#definetoto(x)toto((x)+1)
toto(3) , letextederemplacement final sera
dfinit lamacro toto. Si plusloinonutilise
toto((3)+1) etnonpaslexpressioninfinie (...(((3)+1)+1...)+1 .
Leprprocesseurdfinitautomatiquementlamacro defined,quipermetdetestersiunidentificateur
estconnuduprprocesseur.Sasyntaxeestlasuivante:
defined(identificateur)
et:
#ifdefidentificateur
.
.
.
#endif
76
Chapitre5.LeprprocesseurC
5.4.Manipulationdechanesdecaractresdansles
macros
Leprprocesseurpermetdeffectuerdesoprationssurleschanesdecaractres.Toutargumentde
macropeuttretransformenchanedecaractresdansladfinitiondelamacrosilestprcddu
signe #.Parexemple,lamacrosuivante:
#defineCHAINE(s)#s
transformesonargumentenchanedecaractres.Parexemple:
CHAINE(2+3)
devient:
"2+3"
permetdeconstruireunnombredeuxchiffres:
NOMBRE(2,3)
5.5.Lestrigraphes
LejeudecaractresutilisparlelangageC++comprendtoutesleslettresenmajusculesetenminus
cules,tousleschiffresetlescaractressuivants:
.,;:!?"+^*%=&
|~_#/\{}[]()
<>
Malheureusement,certainsenvironnementssontincapablesdegrerquelquesunsdecescaractres.
Cestpourrsoudreceproblmequelestrigraphesonttcrs.
Lestrigraphessontdessquencesdetroiscaractrescommenantpardeuxpointsdinterrogations.Ils
permettentderemplacerlescaractresquinesontpasaccessiblessurtouslesenvironnements.Vous
nutiliserezdoncsansdoutejamaislestrigraphes,moinsdytreforc.Lestrigraphesdisponibles
sontdfiniscidessous:
77
Chapitre5.LeprprocesseurC
Tableau51.Trigraphes
78
Trigraphe
Caractrederemplacement
??=
??/
??
??(
??)
??!
??<
??>
??
Chapitre6.Modularitdesprogrammeset
gnrationdesbinaires
Lamodularitest lefait, pourunprogramme, dtrecrit enplusieursmorceauxrelativement in
dpendantslesunsdesautres. Lamodularitadnormesavantageslorsdudveloppement dun
programme. Cependant, elleimpliqueunprocessusdegnrationdelexcutableassezcomplexe.
Danscechapitre,nousallonsvoirlintrtdelamodularit,lesdiffrentestapesquipermettentla
gnrationdelexcutableetlinfluencedecestapessurlasyntaxedulangage.
6.1.Pourquoifaireuneprogrammationmodulaire?
Cequicotelepluschereninformatique, cestledveloppementdelogiciel, paslematriel. En
effet, dvelopperunlogiciel demandedutemps, delamaindoeuvrequalifie, et nest pasfacile
(ilyatoujoursdeserreurs).Deplus,leslogicielsdveloppssontsouventspcifiquesuntypede
problmedonn.Pourchaqueproblme,ilfauttoutrefaire.
Cenestpasuntrsbonbilan.Pourvitertouscesinconvnients,unebranchedelinformatiquea
tdveloppe:legnielogiciel.Legnielogicieldonnelesgrandsprincipesappliquerlorsdela
ralisationdunprogramme,delaconceptionladistribution,etsurtouteladuredevieduprojet.
Cesujetdpasselargementlecadredececours,
aussijeneparleraisquedelaspectcodageseul,
cestdirecequiconcerneleC/C++.
Auniveauducodage,leplusimportantestlaprogrammationmodulaire.Lesidesquiensontla
basesontlessuivantes:
diviserletravailenplusieursquipes;
crerdesmorceauxdeprogrammeindpendantsdelaproblmatiqueglobale,
pourdautreslogiciels;
supprimerlesrisquesderreursquonavaitenreprogrammantcesmorceauxchaquefois.
doncrutilisables
Jetiensprciserquelesprincipesdelaprogrammationmodulairenesappliquentpasquauxpro
grammesdveloppspardesquipesdeprogrammeurs. Ilssappliquent aussi auxprogrammeurs
individuels. Eneffetilestplusfacilededcomposerunproblmeenseslments, forcmentplus
simples,quedeletraiterdanssatotalit(dixitDescartes).
Pourparvenircebut,ilestindispensabledepouvoirdcouperunprogrammeensousprogrammes
indpendants,oupresqueindpendants.Pourquechacunpuissetravaillersursapartiedeprogramme,
ilfautquecesmorceauxdeprogrammesoientdansdesfichiersspars.
Pourpouvoirvrifiercesmorceauxdeprogramme,ilfautquelescompilateurspuissentlescompiler
indpendamment, sansavoirlesautresfichiersduprogramme. Ainsi, ledveloppementdechaque
fichierpeutsefairerelativementindpendammentdeceluidesautres.Cependant,cettedivisiondu
travailimpliquedesoprationsassezcomplexespourgnrerlexcutable.
79
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
6.2.Lesdiffrentesphasesduprocessusde
gnrationdesexcutables
Lesphasesduprocessusquiconduisentlexcutablepartirdesfichierssourcesdunprogramme
sontdcritescidessous.CesphasesnesontengnralpasspcifiquesauC++,etmmesilesdif
frentsoutilsdeprogrammationpeuventlescacher, leprocessusdegnrationdesexcutablesse
drouletoujoursselonlesprincipesquisuivent.
Audbutdelagnrationdelexcutable,onnedisposequedesfichierssourcesduprogramme,crit
enC,C++outoutautrelangage(cequisuitnestpasspcifiqueauC/C++).Engnral,lapremire
tapeestletraitementdesfichierssourcesavantcompilation.DanslecasduCetduC++,ilsagitdes
oprationseffectuesparleprprocesseur(remplacementdemacros,suppressiondetexte,inclusion
defichiers...).
Vientensuitelacompilationspare,quiestlefaitdecompilersparmentlesfichierssources.Le
rsultatdelacompilationdunfichiersourceestgnralementunfichierenassembleur,cestdirele
langagedcrivantlesinstructionsdumicroprocesseurdelamachineciblepourlaquelleleprogramme
estdestin.Lesfichiersenassembleurpeuventtretraduitsdirectementencequelonappelledes
fichiersobjets.Lesfichiersobjetscontiennentlatraductionducodeassembleurenlangagemachine.
Ilscontiennentaussidautresinformations,parexemplelesdonnesinitialisesetlesinformations
quiserontutiliseslorsdelacrationdufichierexcutablepartirdetouslesfichiersobjetsgnrs.
Lesfichiersobjetspeuventtreregroupsenbibliothquesstatiques, afinderassembleruncertain
nombredefonctionnalitsquiserontutilisesultrieurement.
Enfin,ltapefinaleduprocessusdecompilationestleregroupementdetouteslesdonnesetdetoutle
codedesfichiersobjetsduprogrammeetdesbibliothques(fonctionsdelabibliothqueCstandardet
desautresbibliothquescomplmentaires),ainsiquelarsolutiondesrfrencesinterfichiers.Cette
tapeestappeleditiondeliens(linkingenanglais).Lersultatdelditiondeliensestlefichier
image,quipourratrechargenmmoireparlesystmedexploitation.Lesfichiersexcutableset
lesbibliothquesdynamiquessontdesexemplesdefichiersimage.
80
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
Figure61.Processusdegnrationdesbinaires
Toutescesoprationspeuventtrergroupesenuneseuletapeparlesoutilsutiliss.Ainsi,lescom
pilateursappellentgnralementleprprocesseuretlassembleurautomatiquement,etralisentpar
foismmelditiondelienseuxmmes.Toutefois,ilrestegnralementpossible,laidedoptions
spcifiqueschaqueoutildedveloppement, dedcomposerlesdiffrentestapesetdobtenirles
fichiersintermdiaires.
Enraisondunombredefichiersimportantetdesdpendancesquipeuventexisterentreeux,lepro
cessusdegnrationdunprogrammeprendtrsviteunecertaineampleur.Lesdeuxproblmesles
pluscourantssontdedterminerlordredanslequellesfichiersetlesbibliothquesdoiventtrecom
pils,ainsiquelesdpendancesentrefichierssourcesetlesfichiersproduitsafindepouvoirregnrer
81
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
correctementlesfichiersimagesaprsunemodificationdessources.Touscesproblmespeuventtre
rsoluslaidedunprogrammeappelmake.Leprincipedemakeesttoujourslemme,mmesi
aucunenormenatdfinieencequileconcerne.makelitunfichier(lefichier( makefile ),
danslequelsetrouventtouteslesoprationsncessairespourcompilerunprogramme.
Puis, illes
excutesicestncessaire.Parexemple,unfichierquiadjtcompiletquinapastmodifi
depuisneserapasrecompil. Cestplusrapide. makesebasesurlesdatesdederniremodifica
tiondesfichierspoursavoirsilsonttmodifis(ilcomparelesdatesdesfichierssourcesetdes
fichiersproduits).Ladatedesfichiersestgreparlesystmedexploitation:ilestdoncimportant
quelordinateursoitlheure.
6.3.CompilationspareenC/C++
LacompilationspareenC/C++sefaitauniveaudufichier.Ilexistetroisgrandstypesdefichiers
sourcesenC/C++:
lesfichiersdentte,quicontiennenttouteslesdclarationscommunesplusieursfichierssources.
Cesont lesfichiersdenttesqui, ensparant ladclarationdeladfinitiondessymbolesdu
programme,permettentdedcouperlensembledessourcesenfichierscompilablessparment;
lesfichiersC,quicontiennentlesdfinitionsdessymbolesenlangageC;
lesfichiersC++,quicontiennentlesdfinitionsdessymbolesenlangageC++.
OnutiliseuneextensiondiffrentepourlesfichiersCet
lesfichiersC++afindelesdiffrencier.
Lesconventionsutilisesdpendentducompilateur.Cependant,onpeutengnraltablirlesrgles
suivantes:
lesfichiersContlextension .c ;
LesprogrammesmodulairesC/C++aurontdonctypiquementlastructuresuivante:
82
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
6.4.Syntaxedesoutilsdecompilation
IlexistevidemmentungrandnombredecompilateursC/C++pourchaqueplateforme.Ilsnesont
malheureusementpascompatiblesauniveaudelalignedecommande.Lemmeproblmeapparat
pourlesditeursdeliens(linkerenanglais)etpourmake.Cependant,quelquesprincipesgnraux
peuventtretablis.Danslasuite,jesupposeraiquelenomducompilateurestcc,queceluidu
prprocesseurestcpp,celuidelditeurdeliensestldetqueceluidemakeestmake.
Engnral,lesdiffrentestapesdelacompilationetdelditiondelienssontregroupesauniveau
ducompilateur,cequipermetdefairelesphasesdetraitementduprprocesseur,decompilationet
dditiondeliensenuneseulecommande. Leslignesdecommandesdescompilateurssont donc
souventcompliquesettrspeuportable.Enrevanche,lasyntaxedemake estunpeuplusportable.
6.4.1.Syntaxedescompilateurs
Lecompilateurdemandeengnral lesnomsdesfichierssourcescompileret lesnomsdesfi
chiersobjetsutiliserlorsdelaphasedditiondeliens.Lorsquelonspcifieunfichiersource,le
compilateurutiliseralefichierobjetquilauracrpourcefichiersourceenplusdesfichiersobjets
donnsdanslalignedecommande. Lecompilateurpeut aussi accepterenlignedecommandele
83
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
cheminderecherchedesbibliothquesdulangageetdesfichiersdentte.Enfin,diffrentesoptions
doptimisationsontdisponibles(maistrspeuportables).Lasyntaxe(simplifie)descompilateursest
souventlasuivante:
cc[fichier.o[...]][[c]fichier.c[...]][oexcutable]
[Lchemin_bibliothques][lbibliothque[...]][Ichemin_include]
fichier.c estlenomdufichiercompiler.Siloption
c leprcde,lefichierseracompil,mais
lditeurdeliensneserapasappel.Sicetteoptionnestpasprsente,lditeurdeliensestappel,
etleprogrammeexcutableformestenregistrdanslefichier a.out.Pourdonnerunautrenom
ceprogramme, ilfaututiliserloption o, suiviedunomdelexcutable. Ilestpossiblededonner
lenomdesfichiersobjetsdjcompils( fichier.o )pourquelditeurdeliensleslieavecle
programmecompil.
Loption L permetdindiquerlechemindurpertoiredesbibliothquesdefonctionsprdfinies.
CerpertoireseraajoutlalistedesrpertoiresindiqusdanslavariabledenvironnementLIBRA
RY_PATH.Loption l demandeaucompilateurdutiliserlabibliothquespcifie,
siellenefait
paspartiedesbibliothquesutilisespardfaut. Demme, loption I permet dedonnerleche
mindaccsaurpertoiredesfichiersinclure(lorsdelutilisationduprprocesseur).Leschemins
ajoutsaveccetteoptionviennentsajouterauxcheminsindiqusdanslesvariablesdenvironnement
C_INCLUDE_PATHetCPLUS_INCLUDE_PATHpourlesprogrammescompilsrespectivementen
CetenC++.
Lordredesparamtressurlalignedecommandeestsignificatif.Lalignedecommandeestexcute
degauchedroite.
Exemple61.Compilationdunfichieretditiondeliens
cccfichier1.c
ccfichier1.oprogramme.ccolancez_moi
6.4.2.Syntaxedemake
Lasyntaxedemakeesttrssimple:
make
84
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
nom:dpendance
Exemple63.Fichiermakefileavecdpendances
#Indiquelesdpendances:
Lancez_moi:fichier1.oprogramme.o
#Indiquecommentcompilerleprogramme:
#(lesymbole$@reprsentelenomdelacible,ici,Lancez_moi)
cco$@fichier1.oprogramme.o
#compilelesdpendances:
fichier1.o:fichier1.c
cccfichier1.c
programme.o:programme1.c
cccprogramme.c
6.5.Problmessyntaxiquesrelatifslacompilation
spare
Pourquelecompilateurpuissecompilerlesfichierssparment,ilfautquevousrespectiezlescondi
tionssuivantes:
chaquetypeouvariableutilisdoittredclar;
Cesconditionsontdesrpercussionssurlasyntaxedesprogrammes.Ellesserontvuesdanslespara
graphessuivants.
85
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
6.5.1.Dclarationdestypes
Lestypesdoiventtoujourstredfinisavanttouteutilisationdansunfichiersource.Parexemple,il
estinterditdutiliserunestructureclientsanslavoirdfinieavantsapremireutilisation.Toutefois,il
estpossibledutiliserunpointeursuruntypededonnesanslavoircompltementdfini.Unesimple
dclarationdutypedebasedupointeursuffiteneffetdanscecasl.
Demme, unsimple class
MaClasse suffitenC++pourdclareruneclassesansladfinircompltement.
6.5.2.Dclarationdesvariables
Lesvariablesquisontdfiniesdansunautrefichierdoiventtredclaresavantleurpremireutilisa
tion.Pourcela,onlesspcifiecommetantdesvariablesexternes,aveclemotclextern :
externinti;
/*iestunentierquiestdclaret
crdansunautrefichier.
Ici,ilestsimplementdclar.
*/
Inversement,siunevariablenedoitpastreaccdeparunautremodule,ilfautdclarercettevariable
statique.Ainsi,mmesiunautrefichierutiliselemotcl extern,ilnepourrapasyaccder.
6.5.3.Dclarationdesfonctions
Lorsquunefonctionsetrouvedfiniedansunautrefichier,ilestncessairedeladclarer.Pourcela,
ilsuffitdedonnersadclaration(lemotcl extern estgalementutilisable,maisfacultatifdansce
cas):
intfactorielle(int);
/*
factorielleestunefonctionattendantcommeparamtre
unentieretrenvoyantunevaleurentire.
Elleestdfiniedansunautrefichier.
*/
86
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
6.5.4.Directivesdditiondeliens
LelangageC++donnelapossibilitdappelerdesfonctionsetdutiliserdesvariablesquiproviennent
dunmodulecrit dansunautrelangage. Pourpermettrecela, il disposededirectivespermettant
dindiquercommentlditiondeliensdoittrefaite. Lasyntaxepermettantderalisercelautilise
lemotcl extern,aveclenomdulangageentreguillemets.Cettedirectivedditiondeliensdoit
prcderlesdclarationsdevariablesetdedonnesconcernes.Siplusieursvariablesoufonctions
utilisentlammedirective, ellespeuventtreregroupesdansunblocdlimitpardesaccolades,
avecladirectivedditiondeliensplacejusteavantcebloc.Lasyntaxeestdonclasuivante:
extern"langage"[dclaration|{
dclaration
[...]
}]
Cependant,lesseulslangagesquuneimplmentationdoitobligatoirementsupportersontleslangages
CetC++.Pourlesautreslangages,aucunenormenestdfinieetlesdirectivesdditionde
lienssontdpendantesdelimplmentation.
Exemple64.DclarationsutilisablesenCetenC++
#ifdef__cplusplus
extern"C"
{
#endif
externintEntierC;
intFonctionC(void);
#ifdef__cplusplus
}
#endif
87
Chapitre6.Modularitdesprogrammesetgnrationdesbinaires
88
Chapitre7.Commentfaireducodeillisible?
Ilestfacile,trsfacile,defairedesprogrammesillisiblesenCouenC++.Ilexistemmeunconcours
ducodeleplusobscur!Celadit,deuxchosespeuventtreditescepropos:
1.anaccrotpaslavitesseduprogramme.Silonveutallerplusvite,ilfautrevoirlalgorithmeou
changerdecompilateur(inutiledefairedelassembleur:lesbonscompilateurssedbrouillent
mieuxquelestrehumainssurceterrain.Lavantagedelassembleurestquel,aumoins,onest
srdavoirunprogrammeillisible.).
2.aaugmenteleschancesdavoirdesbogues.
Sivousvoulezmalgrtoutvousamuser,voiciquelquesconseilsutiles:
crivezdesmacroscomplexesquifontdeseffetsdebordsinsouponnsetquimodifientdesva
riablesglobales;
placezcesoprateursdanslesstructuresdecontrles.Notamment,utilisezloprateurvirgulepour
fairedesinstructionscomposesdanslestestsdu while etdanstouslesmembresdu for.Ilest
souventpossibledemettrelecorpsdu for danslesparenthses;
sincessaire,utiliserlesexpressionscomposes(
choisissezdesnomsdevariableetdefonctionalatoires(pensezunephrase,etprenezlespre
miresoulesdeuximeslettresdesmotsauhasard);
regroupeztouteslesfonctionsdansunmmefichier,parordredenonappariement;
faitesdesfonctionsrallonge;
rajoutezdesparenthsesloellesnesontpasncessaires;
rajoutezdestranstypagesloilsnesontpasncessaires;
necommentezrien,oumieux,donnezdescommentairessansrapportaveclecode.
{ et })danslesstructuresdecontrle;
Exemple71.Programmeparfaitementillisible
/*Quefaitceprogramme?*/
#include <stdio.h>
intmain(void)
{
intzkmlpf,geikgh,wdxaj;
scanf("%u",&zkmlpf);for(wdxaj=0,
geikgh=0;
89
Chapitre7.Commentfaireducodeillisible?
((wdxaj+=++geikgh),geikgh)
<zkmlpf;);
printf("%u",wdxaj);return0;
}
Vouslaurezcompris:ilestplussimplededireicicequilnefautpasfairequededirecommentil
fautfaire.Jeneprtendspasimposerquiconqueunemthodologiequelconque,carchacunestlibre
deprogrammercommeillentend. Eneffet, certainesconventionsdecodagessontaussiabsurdes
quinutilesetellesontlinconvnientdeneplairequceluiquilesacrites(etencore...).Cestpour
cetteraisonquejemesuiscontentdelisterlessourcespotentiellesdillisibilitdesprogrammes.
Sachezdoncsimplementquesivousutilisezunedestechniquesdonnesdansceparagraphe,vous
devriezvousassurerquecestrellementjustifietrevoirvotrecode.Pourobtenirdesprogrammes
lisibles,ilfautsimplementquechacunymettreunpeudusien,cestaussiunemarquedepolitesse
enverslesautresprogrammeurs.
90
Chapitre8.C++:lacoucheobjet
Lacoucheobjet constituesansdoutelaplusgrandeinnovationduC++parrapport
auC. Lebut
delaprogrammationobjetestdepermettreuneabstractionentrelimplmentationdesmoduleset
leurutilisation, apportant ainsi unplusgrandconfort danslaprogrammation. Ellesintgredonc
parfaitementdanslecadredelamodularit.Enfin,lencapsulationdesdonnespermetunemeilleure
protectionetdoncuneplusgrandefiabilitdesprogrammes.
8.1.Gnralits
Thoriquement, ilyaunenettedistinctionentrelesdonnesetlesoprationsquileursontappli
ques.Entoutcas,lesdonnesetlecodenesemlangentpasdanslammoiredelordinateur,sauf
castrsparticuliers(autoprogrammation,aliaspourlechargementdesprogrammesoudesoverlays,
dbogueurs,virus).
Cependant,lanalysedesproblmestraiterseprsentedunemanireplusnaturellesilonconsidre
lesdonnesavecleursproprits.Lesdonnesconstituentlesvariables,etlespropritslesoprations
quonpeutleurappliquer.Decepointdevue,lesdonnesetlecodesontlogiquementinsparables,
mmesilssontplacsendiffrentsendroitsdelammoiredelordinateur.
Cesconsidrationsconduisentlanotiondobjet.Unobjetestunensemblededonnessurlesquelles
desprocdurespeuventtreappliques. Cesprocduresoufonctionsapplicablesauxdonnessont
appelesmthodes.Laprogrammationdunobjetsefaitdoncenindiquantlesdonnesdelobjetet
endfinissantlesprocduresquipeuventluitreappliques.
Ilsepeutquilyaitplusieursobjetsidentiques,dontlesdonnesontbienentendudesvaleursdiff
rentes,maisquiutilisentlemmejeudemthodes.Onditquecesdiffrentsobjetsappartiennent
lammeclassedobjets.Uneclasseconstituedoncunesortedetype,etlesobjetsdecetteclasseen
sontdesinstances.Laclassedfinitdonclastructuredesdonnes,alorsappeleschampsouvariables
dinstances,quelesobjetscorrespondantsauront,ainsiquelesmthodesdelobjet.chaqueinstan
ciation,uneallocationdemmoireestfaitepourlesdonnesdunouvelobjetcr.Linitialisationde
lobjetnouvellementcrestfaiteparunemthodespciale,leconstructeur.Lorsquelobjetestd
truit,uneautremthodeestappele:ledestructeur.Lutilisateurpeutdfinirsespropresconstructeurs
etdestructeursdobjetssincessaire.
Commeseuleslesvaleursdesdonnesdesdiffrentsobjetsduneclassediffrent,lesmthodessont
misesencommunpourtouslesobjetsdunemmeclasse(cestdirequelesmthodesnesontpas
recopies).Pourquelesmthodesappelespourunobjetsachentsurquellesdonnesellesdoivent
travailler,unpointeursurlobjetcontenantcesdonnesleurestpassenparamtre.Cemcanisme
estcompltementtransparentpourleprogrammeurenC++.
Nousvoyonsdoncquenonseulementlaprogrammationorienteobjetestpluslogique,maiselleest
galementplusefficace(lesmthodessontmisesencommun,lesdonnessontspares).
Enfin,lesdonnesdesobjetspeuventtreprotges:cestdirequeseuleslesmthodesdelobjet
peuventyaccder.Cenestpasuneobligation,maiscelaaccrotlafiabilitdesprogrammes.Siune
erreurseproduit,seuleslesmthodesdelobjetdoiventtrevrifies.Deplus,lesmthodesconsti
tuentainsiuneinterfaceentrelesdonnesdelobjetetlutilisateurdelobjet(unautreprogrammeur).
Cetutilisateurnadoncpassavoircommentlesdonnessontgresdanslobjet,ilnedoitutiliser
quelesmthodes.Lesavantagessontimmdiats:ilnerisquepasdefairedeserreursdeprogramma
tionenmodifiantlesdonnesluimme,lobjetestrutilisabledansunautreprogrammeparcequila
uneinterfacestandardise,etonpeutmodifierlimplmentationinternedelobjetsansavoirrefaire
toutleprogramme,pourvuquelesmthodesgardentlemmenom,lesmmesparamtresetlamme
91
Chapitre8.C++:lacoucheobjet
smantique.Cettenotiondeprotectiondesdonnesetdemasquagedelimplmentationinterneaux
utilisateursdelobjetconstituecequelonappellelencapsulation.Lesavantagesdelencapsulation
serontsouventmisenvaleurdanslasuiteautraversdexemples.
Nousallonsentrermaintenantdanslevifdusujet.Celapermettradecomprendrecesgnralits.
8.2.ExtensiondelanotiondetypeduC
IlfautavanttoutsavoirquelacoucheobjetnestpasunsimpleajoutaulangageC,cestunevritable
extension. Eneffet, lesnotionsquelleaapportesonttintgresauCtelpointqueletypage
desdonnesdeCafusionnaveclanotiondeclasse.Ainsi,lestypesprdfinischar,int,double,etc.
reprsententprsentlensembledespropritsdesvariablesayantcetype.Cespropritsconstituent
laclassedecesvariables,etellessontaccessiblesparlesoprateurs.Parexemple,ladditionestune
oprationpouvantportersurdesentiers(entreautres)quirenvoieunobjetdelaclasseentier.
Par
consquent, lestypesdebasesemanipulerontexactementcommedesobjets. Dupointdevuedu
C++,lesutiliserrevientdjfairedelaprogrammationorienteobjet.
Demme,leprogrammeurpeut,laidedelanotiondeclassedobjets,dfinirdenouveauxtypes.Ces
typescomprennentlastructuredesdonnesreprsentesparcestypesetlesoprationsquipeuvent
leurtreappliques.Enfait,leC++assimilecompltementlesclassesaveclestypes,etladfinition
dunnouveautypesefaitdoncendfinissantlaclassedesvariablesdecetype.
8.3.DclarationdeclassesenC++
Afindepermettreladfinitiondesmthodesquipeuventtreappliquesauxstructuresdesclasses
C++, lasyntaxedesstructuresCattendue(et
simplifie). Il est prsent possiblededfinir
compltementdesmthodesdansladfinitiondelastructure.Cependantilestprfrabledelareporter
etdenelaisserqueleurdclarationdanslastructure.Eneffet,celaaccrotlalisibilitetpermetde
masquerlimplmentationdelaclassesesutilisateursenneleurmontrantquesadclarationdans
unfichierdentte.Ilsnepeuventdoncnilavoir,nilamodifier(enrevanche,ilspeuventtoujours
voirlastructurededonnesutiliseparsonimplmentation).
Lasyntaxeestlasuivante:
structNom
{
[typechamps;
[typechamps;
[...]]]
[mthode;
[mthode;
[...]]]
};
o Nom estlenomdelaclasse.Ellepeutcontenirdiverschampsdediverstypes.
Lesmthodespeuvent tredesdfinitionsdefonctions, ouseulement leursdclarations. Si onne
donnequeleursdclarations,ondevralesdfinirplusloin.Pourcela,ilfaudraspcifierlaclasse
laquelleellesappartiennentaveclasyntaxesuivante:
typeclasse::nom(paramtres)
{
92
Chapitre8.C++:lacoucheobjet
/*Dfinitiondelamthode.*/
}
Lasyntaxeestdoncidentiqueladfinitiondunefonctionnormale,
ladiffrenceprsqueleur
nomestprcddunomdelaclasselaquelleellesappartiennentetdedeuxdeuxpoints( ::).Cet
oprateur :: estappelloprateurdersolutiondeporte. Ilpermet, dunemaniregnrale, de
spcifierleblocauquellobjetquilesuitappartient.Ainsi,lefaitdeprcderlenomdelamthode
parlenomdelaclassepermetaucompilateurdesavoirdequelleclassecettemthodefaitpartie.
Rienninterdit, eneffet, davoirdesmthodesdemmesignature, pourvuquellessoientdansdes
classesdiffrentes.
Exemple81.Dclarationdemthodesdeclasse
structEntier
{
inti;
//Donnemembredetypeentier.
//Fonctiondfinielintrieurdelaclasse:
intlit_i(void)
{
returni;
}
//Fonctiondfinielextrieurdelaclasse:
voidecrit_i(intvaleur);
};
voidEntier::ecrit_i(intvaleur)
{
i=valeur;
return;
}
Note:Si lalistedesparamtresdeladfinitiondelafonctioncontient desinitialisationssup
plmentairescellesqui ont tspcifiesdansladclarationdelafonction, lesdeuxjeux
dinitialisationssontfusionnesetutilisesdanslefichieroladfinitiondelafonctionestplace.
Silesinitialisationssontredondantesoucontradictoires,lecompilateurgnreuneerreur.
//Fonctionglobale.
structA
{
93
Chapitre8.C++:lacoucheobjet
inti;
voidfixe(inta)
{
i=a;
return;
}
intvaleur(void)
{
returni;
}
//Mmesignaturequelafonctionglobale.
intglobal_valeur(void)
{
return::valeur();//Accdelafonctionglobale.
}
};
//Premirevariabledeporteglobale
//Variablehomonymedeportelocale.
//jvautprsent2,etnonpas6.
/*Suite...*/
return0;
}
Leschampsduneclassepeuventtreaccdscommedesvariablesnormalesdanslesmthodesde
cetteclasse.
Exemple83.Utilisationdeschampsduneclassedansunedesesmthodes
structclient
{
charNom[21],Prenom[21];
unsignedintDate_Entree;
//Dfinitleclient.
//Datedentreduclient
//danslabasededonnes.
intSolde;
booldans_le_rouge(void)
{
return(Solde<0);
}
boolbon_client(void)
94
//Lebonclientest
Chapitre8.C++:lacoucheobjet
//unancienclient.
{
return(Date_Entree<1993);//Datelimite:1993.
}
};
Danscetexemple,leclientestdfiniparcertainesdonnes.Plusieursmthodessontdfiniesdansla
classemme.
Linstanciationdunobjetsefaitcommecelledunesimplevariable:
classeobjet;
Parexemple,sionaunebasededonnesdevantcontenir100clients,onpeutfaire:
clientclientele[100];
/*Instancie100clients.*/
Lorsquelesfonctionsmembresduneclassesontdfiniesdansladclarationdecetteclasse,lecom
pilateurlesimplmenteen inline (moinsquellesnesoientrcursivesouquilexisteunpointeur
surelles).
Si lesmthodesnesont pasdfiniesdanslaclasse, ladclarationdelaclasseseramisedansun
fichierdentte, etladfinitiondesmthodesserareportedansunfichierC++,
quiseracompil
etliauxautresfichiersutilisantlaclasseclient.
Bienentendu, ilesttoujourspossiblededclarer
lesfonctionsmembrescommetantdesfonctions inline mmelorsquellessontdfiniesendehors
deladclarationdelaclasse.Pourcela,ilfaututiliserlemotcl inline,etplacerlecodedeces
fonctionsdanslefichierdentteoudansunfichier.inl.
Sansfonctionsinline,notreexempledevient:
Fichierclient.h:
structclient
{
charNom[21],Prenom[21];
unsignedintDate_Entree;
intSolde;
booldans_le_rouge(void);
boolbon_client(void);
};
95
Chapitre8.C++:lacoucheobjet
/*
Attentionnepasoublierle;lafindelaclassedansun
fichier.h!Lerreurapparatraitdanstouslesfichiersayant
uneligne#include"client.h",parcequelacompilationalieu
aprslappelauprprocesseur.
*/
Fichierclient.cc:
/*Inclutladclarationdelaclasse:*/
#include"client.h"
/*Dfinitlesmthodesdelaclasse:*/
boolclient::dans_le_rouge(void)
{
return(Solde<0);
}
boolclient::bon_client(void)
{
return(Date_Entree<1993);
}
8.4.Encapsulationdesdonnes
Lesdiverschampsdunestructuresontaccessiblesennimportequelendroitduprogramme.
oprationtellequecelleciestdoncfaisable:
Une
clientele[0].Solde=25000;
Lesoldedunclientpeutdonctremodifisanspasserparunemthodedontceseraitlebut.Elle
pourraitparexemplevrifierquelonnaffectepasunsoldesuprieurausoldemaximalautorispar
leprogramme(labornesuprieuredesvaleursdesentierssigns).
Parexemple, silesentierssont
codssur16bits,cettebornemaximumest32767.Unprogrammequiferait:
clientele[0].Solde=32800;
obtiendraitdoncunsoldede12(valeurennombresigndunombrenonsign32800),alorsquil
espreraitobtenirunsoldepositif!
Ilestpossibledempcherlaccsdeschampsoudecertainesmthodestoutefonctionautreque
cellesdelaclasse.Cetteoprationsappellelencapsulation.Pourlaraliser,ilfaututiliserlesmots
clssuivants:
public
:lesaccssontlibres;
private
96
:lesaccssontautorissdanslesfonctionsdelaclasseseulement;
Chapitre8.C++:lacoucheobjet
:lesaccssontautorissdanslesfonctionsdelaclasseetdesesdescendantes(voir
lasectionsuivante)seulement.Lemotcl protected nestutilisquedanslecadredelhritage
desclasses.Lasectionsuivantedtailleracepoint.
protected
Pourchangerlesdroitsdaccsdeschampsetdesmthodesduneclasse,ilfautfaireprcderceux
:).Parexemple,pourprotgerles
cidumotclindiquantlesdroitsdaccssuividedeuxpoints(
donnesrelativesauclient,onchangerasimplementladclarationdelaclasseen:
structclient
{
private:
//Donnesprives:
charNom[21],Prenom[21];
unsignedintDate_Entree;
intSolde;
//Ilnyapasdemthodeprive.
public:
//Lesdonnesetlesmthodespubliques:
//Ilnyapasdedonnepublique.
booldans_le_rouge(void);
boolbon_client(void)
};
Outrelavrificationdelavaliditdesoprations, lencapsulationacommeintrtfondamentalde
dfiniruneinterfacestablepourlaclasseauniveaudesmthodesetdonnesmembrespubliqueset
protges.Limplmentationdecetteinterface,raliseenpriv,peuttremodifieloisirsanspour
autantperturberlesutilisateursdecetteclasse,tantquecetteinterfacenestpasellemmemodifie.
Pardfaut, lesclassesconstruitesavec struct onttousleursmembrespublics. Ilestpossiblede
dclareruneclassedonttousleslmentssontpardfautprivs.Pourcela,ilsuffitdutiliserlemot
cl class laplacedumotcl struct.
Exemple84.Utilisationdumotclclass
classclient
{
//privateestprsentinutile.
charNom[21],Prenom[21];
unsignedintDate_Entree;
intSolde;
public:
//Lesdonnesetlesmthodespubliques.
booldans_le_rouge(void);
boolbon_client(void);
};
Enfin,ilexisteunderniertypedeclasse,quejemecontenteraidementionner:lesclassesunion.Elles
sedclarentcommelesclasses struct et class, maisaveclemotcl union. Lesdonnessont,
commepourlesunionsduC,situestoutesaummeemplacement,cequifaitqucriredanslune
97
Chapitre8.C++:lacoucheobjet
dentreelleprovoqueladestructiondesautres.Lesunionssonttrssouventutilisesenprogramma
tionsystme,lorsquunpolymorphismephysiquedesdonnesestncessaire(cestdirelorsquelles
doiventtreinterprtesdediffrentesfaonsselonlecontexte).
Note:Lesclassesdetype union nepeuventpasavoirdemthodesvirtuellesetdemembres
statiques.Ellesnepeuventpasavoirdeclassesdebase,ni servirdeclassedebase.Enfin,les
unionsnepeuventpascontenirdesrfrences,nidesobjetsdontlaclasseaunconstructeurnon
trivial,unconstructeurdecopienontrivial
ouundestructeurnontrivial.Pourtoutescesnotions,
voirlasuiteduchapitre.
Lesclassesdfiniesauseinduneautreclassesontconsidrescommefaisantpartiedeleur
private et protected decelle
classehte,etontdoncledroitdaccderauxdonnesmembres
ci.Remarquezquecettergleestassezrcentedanslanormedulangage,etquelaplupartdes
compilateursrefuserontcesaccs.Il faudradoncdclareramiesdelaclassehtelesclasses
quisontdfiniesauseindecelleci.LamaniredeprocderseradcritedanslaSection8.7.2.
8.5.Hritage
Lhritagepermet dedonneruneclassetouteslescaractristiquesduneoudeplusieursautres
classes.Lesclassesdontellehritesontappelesclassesmres,classesdebaseouclassesantc
dentes.Laclasseellemmeestappeleclassefille,classedriveouclassedescendante.
Lespropritshritessontleschampsetlesmthodesdesclassesdebase.
PourfaireunhritageenC++,ilfautfairesuivrelenomdelaclassefilleparlalistedesclassesmres
dansladclarationaveclesrestrictionsdaccsauxdonnes,chaquelmenttantspardesautres
parunevirgule.Lasyntaxe(donnepour class,identiquepour struct)estlasuivante:
classClasse_mere1
{
/*Contenudelaclassemre1.*/
};
[classClasse_mere2
{
/*Contenudelaclassemre2.*/
};]
[...]
classClasse_fille:public|protected|privateClasse_mere1
[,public|protected|privateClasse_mere2[...]]
{
/*Dfinitiondelaclassefille.*/
};
98
Chapitre8.C++:lacoucheobjet
Tableau81.Droitsdaccssurlesmembreshrits
motclutilispourlhritage
Accsauxdonnes
motclutilis
public
protected
private
public
public
protected
private
pourleschamps
protected
protected
protected
private
etlesmthodes
private
interdit
interdit
interdit
Ainsi,lesdonnespubliquesduneclassemredeviennentsoitpubliques,soitprotges,soitprives
selonquelaclassefillehriteenpublic,protgouenpriv.Lesdonnesprivesdelaclassemre
sonttoujoursinaccessibles,etlesdonnesprotgesdeviennentsoitprotges,soitprives.
Ilestpossibledomettrelesmotsclspublic, protected et private danslasyntaxedelhritage.
Lecompilateurutiliseuntypedhritagepardfautdanscecas.Lesclassesdetypestruct utilisent
lhritage public pardfautetlesclassesdetype class utilisentlemotcl private pardfaut.
Exemple85.Hritagepublic,privetprotg
classEmplacement
{
protected:
intx,y;
//Donnesnepouvanttreaccdes
//queparlesclassesfilles.
public:
voidChange(int,int);//Mthodetoujoursaccessible.
};
voidEmplacement::Change(inti,intj)
{
x=i;
y=j;
return;
}
classPoint:publicEmplacement
{
protected:
unsignedintcouleur; //Donneaccessible
//auxclassesfilles.
public:
voidSetColor(unsignedint);
};
voidPoint::SetColor(unsignedintNewColor)
{
couleur=NewColor;
//Dfinitlacouleur.
return;
}
SiuneclasseCercledoithriterdedeuxclassesmres,parexempleEmplacementetForme,sad
clarationauralaformesuivante:
99
Chapitre8.C++:lacoucheobjet
classCercle:publicEmplacement,publicForme
{
/*
DfinitiondelaclasseCercle.Cetteclassehrite
desdonnespubliquesetprotgesdesclassesEmplacement
etForme.
*/
};
Ilestpossiblederedfinirlesfonctionsetlesdonnesdesclassesdebasedansuneclassedrive.
Parexemple,siuneclasseBdrivedelaclasseA,etquetoutesdeuxcontiennentunedonne d,les
instancesdelaclasseButiliserontladonned delaclasseBetlesinstancesdelaclasseAutiliseront
ladonne d delaclasseA.Cependant,lesobjetsdeclasseBcontiendrontgalementunsousobjet,
luimmeinstancedelaclassedebaseA.Parconsquent,ilscontiendrontladonne
d delaclasseA,
maiscettedernireseracacheparladonne d delaclasselaplusdrive,savoirlaclasseB.
Cemcanismeestgnral:quanduneclassedriveredfinitunmembreduneclassedebase,ce
membreestcachetonnepeutplusaccderdirectementquaumembreredfini(celuidelaclasse
drive).Cependant,ilestpossibledaccderauxdonnescachessilonconnatleurclasse,pour
cela, ilfautnommerlemembrecompltementlaidedeloprateurdersolutiondeporte( ::).
Lenomcompletdunmembreestconstitudunomdesaclassesuivideloprateurdersolutionde
porte,suivisdunomdumembre:
classe::membre
Exemple86.Oprateurdersolutiondeporteetmembredeclassesdebase
structBase
{
inti;
};
structDerivee:publicBase
{
inti;
intLitBase(void);
};
intDerivee::LitBase(void)
{
returnBase::i;//Renvoielavaleuridelaclassedebase.
}
intmain(void)
{
DeriveeD;
D.i=1;
D.Base::i=2;
return0;
}
100
//AccdelentieridelaclasseDerivee.
//AccdelentieridelaclasseBase.
Chapitre8.C++:lacoucheobjet
8.6.Classesvirtuelles
SupposonsprsentquuneclasseDhritededeuxclassesmres,
lesclassesBetC. Supposons
galementquecesdeuxclasseshritentduneclassemrecommuneappeleclasseA.Onalarbre
gnalogiquesuivant:
OnsaitqueBetChritentdesdonnesetdesmthodespubliquesetprotgesdeA.Demme,D
hritedesdonnesdeBetC,etparleurintermdiairedesdonnesdeA.Ilseposedoncleproblme
suivant:quellessontlesdonnesquelondoitutiliserquandonrfrenceleschampsdeA?Celles
deBoucellesdeC?OnpeutaccderauxdeuxsousobjetsdeclasseAenspcifiantlechemin
suivredanslarbregnalogiquelaidedeloprateurdersolutiondeporte.Cependant,celanest
nipratiqueniefficace,etengnral,onsattendcequuneseulecopiedeAapparaissedansD.
Leproblmeest rsoluendclarant virtuellelaclassedebasecommunedanslaspcificationde
lhritagepourlesclassesfilles. Lesdonnesdelaclassedebaseneserontalorsplusdupliques.
Pourdclareruneclassemrecommeuneclassevirtuelle,ilfautfaireprcdersonnomdumotcl
virtual danslhritagedesclassesfilles.
Exemple87.Classesvirtuelles
classA
{
protected:
intDonnee;
};
//Ladonnedelaclassedebase.
//HritagedelaclasseA,virtuelle:
classB:virtualpublicA
{
protected:
intValeur_B;
//Autredonneque"Donnee"(hrite).
};
//Aesttoujoursvirtuelle:
classC:virtualpublicA
{
101
Chapitre8.C++:lacoucheobjet
protected:
intvaleur_C;
//Autredonne
//("Donnee"estacquiseparhritage).
};
classD:publicB,publicC
//Ici,Donneenestpasdupliqu.
{
/*DfinitiondelaclasseD.*/
};
Note:Normalement,lhritageestralisparlecompilateurparaggrgationdelastructurede
donnesdesclassesdebasedanslastructurededonnesdelaclassedrive.Pourlesclasses
virtuelles,cenestengnralpaslecas,puisquelecompilateurdoitassurerlunicitdesdonnes
hritesdecesclasses,mmeencasdhritagemultiple.Parconsquent,certainesrestrictions
dusagesappliquentsurlesclassesvirtuelles.
Premirement,il estimpossibledetranstyperdirectementunpointeursurunobjetduneclasse
debasevirtuelleenunpointeursurunobjetdunedesesclassesdrives.Ilfautimprativement
utiliserloprateurdetranstypagedynamique dynamic_cast .Cetoprateurseradcritdansle
Chapitre10.
Deuximement,chaqueclassedrivedirectementouindirectementduneclassevirtuelledoit
enappelerleconstructeurexplicitementdanssonconstructeursiceluiciprenddesparamtres.
Eneffet,ellenepeutpassefieraufaitquuneautredesesclassesdebase,ellemmedrive
delaclassedebasevirtuelle,appelleunconstructeurspcifique,carilestpossiblequeplusieurs
classesdebasecherchentinitialiserdiffremmentchacuneunobjetcommunhritdelaclasse
virtuelle.Pourreprendrelexempledonncidessus,silesclassesBetCappellaienttoutesles
deuxunconstructeurnontrivialdelaclassevirtuelleA,etquelaclasseDappellaitellemme
lesconstructeursdeBetC,lesousobjethritdeAseraitconstruitplusieursfois.Pourviter
cela,lecompilateurignorepurementetsimplementlesappelsauconstructeurdesclassesde
basesvirtuellesdanslesclassesdebasedrives.Ilfautdoncsystmatiquementlespcifier,
chaqueniveaudelahirarchiedeclasse.LanotiondeconstructeurseravuedanslaSection8.8
8.7.Fonctionsetclassesamies
Ilestparfoisncessairedavoirdesfonctionsquiontunaccsillimitauxchampsduneclasse.En
gnral,lemploidetellesfonctionstraduitunmanquedanalysedanslahirarchiedesclasses,mais
pastoujours.Ellesrestentdoncncessairesmalgrtout.
Detellesfonctionssontappelesdesfonctionsamies.Pourquunefonctionsoitamieduneclasse,il
fautquellesoitdclaredanslaclasseaveclemotcl friend.
Ilestgalementpossibledefaireuneclasseamieduneautreclasse,maisdanscecas,cetteclasse
devraitpeuttretreuneclassefille.Lutilisationdesclassesamiespeuttraduireundfautdeconcep
tion.
8.7.1.Fonctionsamies
Lesfonctionsamiessedclarentenfaisantprcderladclarationclassiquedelafonctiondumotcl
friend lintrieurdeladclarationdelaclassecible.Lesfonctionsamiesnesontpasdesmthodes
delaclassecependant(celanauraitpasdesenspuisquelesmthodesontdjaccsauxmembresde
laclasse).
102
Chapitre8.C++:lacoucheobjet
Exemple88.Fonctionsamies
classA
{
inta;
friendvoidecrit_a(inti);
};
//Unedonneprive.
//Unefonctionamie.
Aessai;
voidecrit_a(inti)
{
essai.a=i;
return;
}
//Initialisea.
Ilestpossiblededclareramieunefonctionduneautreclasse,enprcisantsonnomcompletlaide
deloprateurdersolutiondeporte.
8.7.2.Classesamies
Pourrendretouteslesmthodesduneclasseamiesduneautreclasse,ilsuffitdedclarerlaclasse
compltecommetantamie. Pourcela, ilfautencoreunefoisutiliserlemotcl friend avantla
dclarationdelaclasse,lintrieurdelaclassecible.Cettefoisencore,laclasseamiedclarene
serapasunesousclassedelaclassecible,maisbienuneclassedeporteglobale.
Note:Lefait,pouruneclasse,dapparteniruneautreclasselui donneledroitdaccderaux
membresdesaclassehte. Il nest doncpasncessairededclareramiesduneclasseles
classesdfiniesauseindecelleci.Remarquezquecettergleatrcemmentmodifiedans
lanormeC++,etquelaplupartdescompilateursrefuserontauxclassesinclusesdaccderaux
membresnonpublicsdeleurconteneur.
Exemple89.Classeamie
#include <stdio.h>
classHote
{
friendclassAmie;
inti;
//TouteslesmthodesdeAmiesontamies.
//DonneprivedelaclasseHote.
public:
Hote(void)
{
i=0;
return;
}
};
Hoteh;
classAmie
103
Chapitre8.C++:lacoucheobjet
{
public:
voidprint_hote(void)
{
printf("%d\n",h.i);//Accdeladonneprivedeh.
return;
}
};
intmain(void)
{
Amiea;
a.print_hote();
return0;
}
Onremarqueraplusieurschosesimportantes.Premirement,lamitinestpastransitive.Celasignifie
quelesamisdesamisnesontpasdesamis.UneclasseAamieduneclasseB,ellemmeamiedune
classeC,nestpasamiedelaclasseCpardfaut.Ilfautladclareramieexplicitementsiondsire
quellelesoit. Deuximement, lesamisnesontpashrits. Ainsi, siuneclasseAestamiedune
classeBetquelaclasseCestuneclassefilledelaclasseB,alorsAnestpasamiedelaclasseCpar
dfaut.Encoreunefois,ilfautladclareramieexplicitement.Cesremarquessappliquentgalement
auxfonctionsamies(unefonctionamieduneclasseAamieduneclasseBnestpasamiedelaclasse
B,nidesclassesdrivesdeA).
8.8.Constructeursetdestructeurs
Leconstructeuretledestructeursontdeuxmthodesparticuliresquisontappelesrespectivement
lacrationetladestructiondunobjet.Touteclasseaunconstructeuretundestructeurpardfaut,
fournisparlecompilateur.Cesconstructeursetdestructeursappellentlesconstructeurspardfautet
lesdestructeursdesclassesdebaseetdesdonnesmembresdelaclasse,maisendehorsdecela,ils
nefontabsolumentrien.Ilestdoncsouventncessairedelesredfinirafindegrercertainesactions
quidoiventavoirlieulorsdelacrationdunobjetetdeleurdestruction.Parexemple,silobjetdoit
contenirdesvariablesallouesdynamiquement,ilfautleurrserverdelammoirelacrationde
lobjetouaumoinsmettrelespointeurscorrespondantsNULL.ladestructiondelobjet,ilconvient
derestituerlammoirealloue,silenatallou.Onpeuttrouverbiendautressituationsoune
phasedinitialisationetunephasedeterminaisonsontncessaires.
Dsquunconstructeur ouundestructeur atdfini par lutilisateur, lecompilateur nedfinit
plusautomatiquementleconstructeurouledestructeurpardfautcorrespondant.
Enparticulier, si
lutilisateurdfinitunconstructeurprenantdesparamtres,ilneserapluspossibledeconstruireun
objetsimplement,sansfournirlesparamtresceconstructeur,moinsbienentendudedfinirga
lementunconstructeurquineprennepasdeparamtres.
8.8.1.Dfinitiondesconstructeursetdesdestructeurs
Leconstructeursedfinitcommeunemthodenormale.Cependant,pourquelecompilateurpuisse
lareconnatreentantqueconstructeur,lesdeuxconditionssuivantesdoiventtrevrifies:
104
elledoitporterlemmenomquelaclasse;
Chapitre8.C++:lacoucheobjet
ellenedoitavoiraucuntype,pasmmeletypevoid.
Ledestructeurdoitgalementrespectercesrgles.Pourlediffrencierduconstructeur,sonnomsera
toujoursprcddusignetilde(~).
Unconstructeurestappelautomatiquementlorsdelinstanciationdelobjet.Ledestructeurestap
pelautomatiquement lorsdesadestruction. Cettedestructionalieulorsdelasortiedublocde
portecourantepourlesobjetsdeclassedestockage auto.Pourlesobjetsallousdynamiquement,
leconstructeuretledestructeursontappelsautomatiquementparlesexpressionsquiutilisentles
oprateurs new, new[], delete et delete[].Cestpourcelaquilestrecommanddelesutiliser
laplacedesfonctions malloc et free duCpourcrerdynamiquementdesobjets.Deplus,ilne
fautpasutiliser delete ou delete[] surdespointeursdetypevoid,carilnexistepasdobjetsde
typevoid.Lecompilateurnepeutdoncpasdterminerquelestledestructeurappeleraveccetype
depointeur.
Leconstructeurestappelaprslallocationdelammoiredelobjetetledestructeurestappelavant
lalibrationdecettemmoire.Lagestiondelallocationdynamiquedemmoireaveclesclassesest
ainsisimplifie.Danslecasdestableaux,lordredeconstructionestceluidesadressescroissantes,et
lordrededestructionestceluidesadressesdcroissantes.Cestdanscetordrequelesconstructeurs
etdestructeursdechaquelmentdutableausontappels.
Lesconstructeurspourrontavoirdesparamtres.Ilspeuventdonctresurchargs,maispaslesdes
tructeurs.Celaestdafaitquengnralonconnatlecontextedanslequelunobjetestcr,mais
quonnepeutpasconnatrelecontextedanslequelilestdtruit:ilnepeutdoncyavoirquunseul
destructeur.Lesconstructeursquineprennentpasdeparamtreoudonttouslesparamtresontune
valeurpardfaut,remplacentautomatiquementlesconstructeurspardfautdfinisparlecompilateur
lorsquilnyaaucunconstructeurdanslesclasses.
Celasignifiequecesontcesconstructeursqui
serontappelsautomatiquementparlesconstructeurspardfautdesclassesdrives.
Exemple810.Constructeursetdestructeurs
classchaine
{
char*s;
//Implmenteunechanedecaractres.
//Lepointeursurlachanedecaractres.
public:
chaine(void);
chaine(unsignedint);
~chaine(void);
};
chaine::chaine(void)
{
s=NULL;
return;
}
//Leconstructeurpardfaut.
//Leconstructeur.Ilnapasdetype.
//Ledestructeur.
//Lachaneestinitialiseavec
//lepointeurnul.
chaine::chaine(unsignedintTaille)
{
s=newchar[Taille+1];//Allouedelammoirepourlachane.
s[0]=\0;
//Initialiselachane"".
return;
}
chaine::~chaine(void)
105
Chapitre8.C++:lacoucheobjet
{
if(s!=NULL)delete[]s;//Restituelammoireutilisesi
//ncessaire.
return;
}
Pourpasserlesparamtresauconstructeur,ondonnelalistedesparamtresentreparenthsesjuste
aprslenomdelobjetlorsdesoninstanciation:
chaines1;
chaines2(200);
//Instancieunechanedecaractres
//noninitialise.
//Instancieunechanedecaractres
//de200caractres.
Lesconstructeursdevrontparfoiseffectuerdestchespluscompliquesquecellesdonnesdanscet
exemple. Engnral, ilspeuvent fairetouteslesoprationsfaisablesdansunemthodenormale,
saufutiliserlesdonnesnoninitialisesbienentendu. Enparticulier, lesdonnesdessousobjets
dunobjetnesontpasinitialisestantquelesconstructeursdesclassesdebasenesontpasappels.
Cestpourcelaquilfauttoujoursappelerlesconstructeursdesclassesdebaseavantdexcuterle
constructeurdelaclasseencoursdinstanciation. Silesconstructeursdesclassesdebasenesont
pasappelsexplicitement, lecompilateurappellera, pardfaut, lesconstructeursdesclassesmres
quineprennentpasdeparamtreoudonttouslesparamtresontunevaleurpardfaut(et,siaucun
constructeurnestdfinidanslesclassemres,ilappelleralesconstructeurspardfautdecesclasses).
Commentappelerlesconstructeursetlesdestructeursdesclassesmreslorsdelinstanciationetdela
destructionduneclassedrive?Lecompilateurnepeuteneffetpassavoirquelconstructeurilfaut
appelerparmilesdiffrentsconstructeurssurchargspotentiellementprsents...Pourappelerunautre
constructeurduneclassedebasequeleconstructeurneprenantpasdeparamtre, ilfautspcifier
explicitementceconstructeuravecsesparamtresaprslenomduconstructeurdelaclassefille,en
lessparantdedeuxpoints(:).
Enrevanche,ilestinutiledeprciserledestructeurappeler,puisqueceluiciestunique.Leprogram
meurnedoitdoncpasappelerluimmelesdestructeursdesclassesmres,lelangagesencharge.
Exemple811.Appelduconstructeurdesclassesdebase
/*Dclarationdelaclassemre.*/
classMere
{
intm_i;
public:
Mere(int);
~Mere(void);
};
/*Dfinitionduconstructeurdelaclassemre.*/
Mere::Mere(inti)
{
m_i=i;
printf("Excutionduconstructeurdelaclassemre.\n");
return;
}
106
Chapitre8.C++:lacoucheobjet
/*Dfinitiondudestructeurdelaclassemre.*/
Mere::~Mere(void)
{
printf("Excutiondudestructeurdelaclassemre.\n");
return;
}
/*Dclarationdelaclassefille.*/
classFille:publicMere
{
public:
Fille(void);
~Fille(void);
};
/*Dfinitionduconstructeurdelaclassefille
avecappelduconstructeurdelaclassemre.*/
Fille::Fille(void):Mere(2)
{
printf("Excutionduconstructeurdelaclassefille.\n");
return;
}
/*Dfinitiondudestructeurdelaclassefille
avecappelautomatiquedudestructeurdelaclassemre.*/
Fille::~Fille(void)
{
printf("Excutiondudestructeurdelaclassefille.\n");
return;
}
Lorsdelinstanciationdunobjetdelaclassefille,leprogrammeafficheradanslordrelesmessages
suivants:
Excutionduconstructeurdelaclassemre.
Excutionduconstructeurdelaclassefille.
etlorsdeladestructiondelobjet:
Excutiondudestructeurdelaclassefille.
Excutiondudestructeurdelaclassemre.
Si lonnavait pasprcisqueleconstructeurappelerpourlaclasseMeretait
leconstructeur
prenantunentierenparamtre,lecompilateurauraitessaydappelerleconstructeurpardfautde
cetteclasse.Or,ceconstructeurntantplusgnrautomatiquementparlecompilateur(causede
ladfinitiondunconstructeurprenantunparamtre),ilyauraiteuuneerreurdecompilation.
Ilestpossibledappelerplusieursconstructeurssilaclassedrivedeplusieursclassesdebase.Pour
cela,ilsuffitdelisterlesconstructeursunun,ensparantleursappelspardesvirgules.Onnotera
cependant quelordredanslequel lesconstructeurssont appelsnest pasforcment lordredans
lequel ilssont listsdansladfinitionduconstructeurdelaclassefille.
Eneffet, leC++appelle
107
Chapitre8.C++:lacoucheobjet
toujourslesconstructeursdanslordredapparitiondeleursclassesdanslalistedesclassesdebase
delaclassedrive.
leplusdrivdansune
Note:Afindviterlutilisationdesdonnesnoninitialisesdelobjet
hirarchiependantlaconstructiondesessousobjetsparlintermdiairedesfonctionsvirtuelles,
lemcanismedesfonctionsvirtuellesest dsactivdanslesconstructeurs(voyezlaSection
8.13pourplusdedtailssurlesfonctionsvirtuelles).Ceproblmesurvientparcequependant
lexcutiondesconstructeursdesclassesdebase,lobjetdelaclasseencoursdinstanciation
napasencoretinitialis,etmalgrcela,unefonctionvirtuelleauraitpuutiliserunedonnede
cetobjet.
Unefonctionvirtuellepeut donctoujourstreappeledansunconstructeur, maislafonction
effectivementappeleestcelledelaclassedusousobjetencoursdeconstruction:pascellede
laclassedelobjetcomplet.Ainsi,siuneclasseAhriteduneclasseBetquellesonttoutesles
deuxunefonctionvirtuelle f,lappel de f dansleconstructeurdeButiliseralafonction f deB,
pascelledeA(mmesilobjetqueloninstancieestdeclasseA).
108
Chapitre8.C++:lacoucheobjet
leconstructeurdecettedernireclasseserait appelplusieursfois, ventuellement avecdes
valeursdeparamtresdiffrentes. Chaqueclassedoit doncprendreenchargelaconstruction
dessousobjetsdesclassesdebasevirtuellesdontilhritedanscecas.
8.8.2.Constructeursdecopie
Ilfaudraparfoiscrerunconstructeurdecopie.
Lebutdecetypedeconstructeurestdinitialiser
unobjetlorsdesoninstanciationpartirdunautreobjet.
Touteclassedisposedunconstructeur
decopiepardfautgnrautomatiquementparlecompilateur,dontleseulbutestderecopierles
champsdelobjetrecopierunundansleschampsdelobjetinstancier.Toutefois,ceconstructeur
pardfautnesuffirapastoujours,etleprogrammeurdevraparfoisenfournirunexplicitement.
Ceseranotammentlecaslorsquecertainesdonnesdesobjetsauronttallouesdynamiquement.
Unecopiebrutaledeschampsdunobjetdansunautreneferaitquerecopierlespointeurs,pasles
donnespointes.Ainsi,lamodificationdecesdonnespourunobjetentraneraitlamodificationdes
donnesdelautreobjet,cequineseraitsansdoutepasleffetdsir.
Ladfinitiondesconstructeursdecopiesefaitcommecelledesconstructeursnormaux.Lenomdoit
treceluidelaclasse,etilnedoityavoiraucuntype.Danslalistedesparamtrescependant,ildevra
toujoursyavoirunerfrencesurlobjetcopier.
Pourlaclassechainedfiniecidessus,ilfautunconstructeurdecopie.Celuicipeuttredclarde
lafaonsuivante:
chaine(constchaine&Source);
o Source estlobjetcopier.
Si lonrajouteladonnemembre
constructeurpeuttre:
Taille
dansladclarationdelaclasse,
ladfinitiondece
chaine::chaine(constchaine&Source)
{
inti=0;
//Compteurdecaractres.
Taille=Source.Taille;
s=newchar[Taille+1];
//Effectuelallocation.
strcpy(s,Source.s);
//Recopielachanedecaractressource.
return;
}
Danslesdeuxexemples,cestleconstructeurdecopiequiestappel.Enparticulier,ladeuxime
ligne,leconstructeurnormalnestpasappeletaucuneaffectationentreobjetsnalieu.
109
Chapitre8.C++:lacoucheobjet
Note:Lefaitdedfinirunconstructeurdecopiepouruneclassesignifiegnralementquele
constructeurdecopie,ledestructeuretloprateurdaffectationfournispardfautparlecompi
lateurneconviennent paspourcetteclasse. Parconsquent, cesmthodesdevront systma
tiquementtreredfiniestouteslestroisdsquelunedentreellelesera.Cettergle,quelon
appellela rgle des trois,vouspermettradviterdesboguesfacilement.Voustrouverezdeplus
amplesdtailssurlamanirederedfinirloprateurdaffectationdanslaSection8.11.3.
8.8.3.Utilisationdesconstructeursdanslestranstypages
Lesconstructeurssont utilissdanslesconversionsdetypedanslesquellesletypecibleest
celui
delaclasseduconstructeur.Cesconversionspeuventtresoitimplicites(dansuneexpression),soit
explicite(laideduntranstypage).Pardfaut,lesconversionsimplicitessontlgales,pourvuquil
existeunconstructeurdontlepremierparamtrealemmetypequelobjetsource.Parexemple,la
classeEntiersuivante:
classEntier
{
inti;
public:
Entier(intj)
{
i=j;
return;
}
};
disposedunconstructeurdetranstypagepourlesentiers.Lesexpressionssuivantes:
intj=2;
Entiere1,e2=j;
e1=j;
sontdonclgales,lavaleurentiresitueladroitedelexpressiontantconvertieimplicitementen
unobjetdutypedelaclasseEntier.
Si,pouruneraisonquelconque,cecomportementnestpassouhaitable,onpeutforcerlecompilateur
naccepterquelesconversionsexplicites(laidedetranstypage).Pourcela,ilsuffitdeplacerlemot
cl explicit avantladclarationduconstructeur.Parexemple,leconstructeurdelaclassechaine
vuecidessusprenantunentierenparamtrerisquedtreutilisdansdesconversionsimplicites.
Orceconstructeurnepermetpasdeconstruireunechanedecaractrespartirdunentier,
etne
doitdoncpastreutilisdanslesoprationsdetranstypage.Ceconstructeurdoitdonctredclar
explicit :
classchaine
{
size_tTaille;
char*s;
public:
chaine(void);
//Ceconstructeurpermetdeprciserlatailledelachane
//sacration:
110
Chapitre8.C++:lacoucheobjet
explicitchaine(unsignedint);
~chaine(void);
};
Aveccettedclaration,lexpressionsuivante:
intj=2;
chaines=j;
nestplusvalide,alorsquelleltaitlorsqueleconstructeurntaitpasdclar explicit.
Note:Onprendragardeaufaitquelemotcl explicit nempchelutilisationduconstructeur
danslesoprationsdetranstypagequedanslesconversionsimplicites.Siletranstypageestex
plicitementdemand,leconstructeurseramalgrtoututilis.Ainsi,lecodesuivantseraaccept:
intj=2;
chaines=(chaine)j;
Bienentendu,celanapasbeaucoupdesignificationetnedevraitjamaistreeffectu.
8.9.Pointeurthis
Nousallonsprsentvoircommentlesfonctionsmembres, quiappartiennentlaclasse, peuvent
accderauxdonnesdunobjet,quiestuneinstancedecetteclasse.Celaestindispensablepourbien
comprendrelesparagraphessuivants.
chaqueappeldunefonctionmembre,lecompilateurpasseimplicitementunpointeursurlesdon
nesdelobjetenparamtre.Ceparamtreestlepremierparamtredelafonction.Cemcanismeest
compltementinvisibleauprogrammeur,etnousnenousattarderonspasdessus.
Enrevanche,ilfautsavoirquelepointeursurlobjetestaccessiblelintrieurdelafonctionmembre.
Il portelenom this . Parconsquent, *this reprsentelobjet luimme. Nousverronsune
utilisationde this dansleparagraphesuivant(surchargedesoprateurs).
this estunpointeurconstant,cestdirequonnepeutpaslemodifier(ilestdoncimpossiblede
fairedesoprationsarithmtiquesdessus).Celaesttoutfaitnormal,puisquelefairereviendrait
sortirdelobjetencours(celuipourlequellamthodeencoursdexcutiontravaille).
Ilestpossibledetransformercepointeurconstantenunpointeurconstantsurdesdonnesconstantes
pourchaquefonctionmembre.Lepointeurnepeuttoujourspastremodifi,etlesdonnesdelobjet
nepeuventpastremodifiesnonplus.Lobjetestdoncconsidrparlafonctionmembreconcerne
commeunobjetconstant.Celarevientdirequelafonctionmembresinterditlamodificationdes
const lasuitedelenttedela
donnesdelobjet.Onparvientcersultatenajoutantlemotcl
fonctionmembre.Parexemple:
classEntier
{
inti;
public:
111
Chapitre8.C++:lacoucheobjet
intlit(void)const;
};
intEntier::lit(void)const
{
returni;
}
Danslafonctionmembre lit,ilestimpossibledemodifierlobjet.Onnepeutdoncaccderquen
lectureseule i.NousverronsuneapplicationdecettepossibilitdanslaSection8.15.
Ilestnoterquunemthodequinestpasdclarecommetant const modifieapriorilesdonnes
delobjetsurlequelelletravaille. Donc, sielleestappelesurunobjetdclar const, uneerreur
decompilationseproduit.Cecomportementestnormal.Ondevradonctoujoursdclarer const une
mthodequinemodifiepasrellementlobjet,afindelaisserlutilisateurlechoixdedclarer const
ounonlesobjetsdesaclasse.
Note:Lemot cl const nintervient pasdanslasignaturedesfonctionsengnral lorsquil
sappliqueauxparamtres(toutparamtredclarconst perdsaqualificationdanslasignature).
Enrevanche, il intervientdanslasignaturedunefonctionmembrequandil sappliquecette
fonction(ou,plusprcisment,lobjetpointpar this).Il estdoncpossiblededclarerdeux
fonctionsmembresacceptantlesmmesparamtres,dontuneseuleestconst.Lorsdelappel,
ladterminationdelafonctionutiliser dpendradelanaturedelobjet
sur lequel elledoit
sappliquer.Silobjetest const,lamthodeappeleseracellequiest const.
8.10.Donnesetfonctionsmembresstatiques
Nousallonsvoirdansceparagraphelemploidumotcl static danslesclasses.Cemotclinter
vientpourcaractriserlesdonnesmembresstatiquesdesclasses, lesfonctionsmembresstatiques
desclasses,etlesdonnesstatiquesdesfonctionsmembres.
8.10.1.Donnesmembresstatiques
Uneclassepeutcontenirdesdonnesmembresstatiques.Cesdonnessontsoitdesdonnesmembres
propreslaclasse,soitdesdonneslocalesstatiquesdesfonctionsmembresdelaclasse.Danstous
lescas,ellesappartiennentlaclasse,etnonpasauxobjetsdecetteclasse.Ellessontdonccommunes
touscesobjets.
Ilestimpossibledinitialiserlesdonnesduneclassedansleconstructeurdelaclasse,carleconstruc
teurninitialisequelesdonnesdesnouveauxobjets.Lesdonnesstatiquesnesontpasspcifiques
unobjetparticulieretnepeuventdoncpastreinitialisesdansleconstructeur.Enfait,leurinitia
lisationdoitsefairelorsdeleurdfinition,endehorsdeladclarationdelaclasse.Pourprciserla
classelaquellelesdonnesainsidfiniesappartiennent,ondevrautiliserloprateurdersolution
deporte( ::).
Exemple813.Donnemembrestatique
classtest
{
112
Chapitre8.C++:lacoucheobjet
staticinti;
...
//Dclarationdanslaclasse.
};
inttest::i=3;
//Initialisationendehorsdelaclasse.
3.
Note:Ladfinitiondesdonnesmembresstatiquessuitlesmmesrglesqueladfinitiondes
variablesglobales.Autrementdit,ellessecomportentcommedesvariablesdclaresexternes.
Ellessontdoncaccessiblesdanstouslesfichiersduprogramme(pourvu,bienentendu,quelles
soientdclaresenzonepubliquedanslaclasse).Demme,ellesnedoiventtredfiniesquune
seulefoisdanstoutleprogramme.Ilnefautdoncpaslesdfinirdansunfichierdenttequipeut
treinclusplusieursfoisdansdesfichierssources,
mmesi lonprotgecefichierdentte
contrelesinclusionsmultiples.
Lesvariablesstatiquesdesfonctionsmembresdoivent treinitialiseslintrieurdesfonctions
membres.Ellesappartiennentgalementlaclasse,etnonpasauxobjets.Deplus,leurporteest
rduitecelledublocdanslequelellesonttdclares.Ainsi,lecodesuivant:
#include <stdio.h>
classtest
{
public:
intn(void);
};
inttest::n(void)
{
staticintcompte=0;
returncompte++;
}
intmain(void)
{
testobjet1,objet2;
printf("%d",objet1.n()); //Affiche0
printf("%d\n",objet2.n()); //Affiche1
return0;
}
8.10.2.Fonctionsmembresstatiques
Lesclassespeuventgalementcontenirdesfonctionsmembresstatiques.Celapeutsurprendrepre
mirevue,puisquelesfonctionsmembresappartiennentdjlaclasse,cestdiretouslesobjets.
Enfait,celasignifiequecesfonctionsmembresnerecevrontpaslepointeursurlobjetthis,comme
cest lecaspourlesautresfonctionsmembres. Parconsquent, ellesnepourront accderquaux
donnesstatiquesdelobjet.
113
Chapitre8.C++:lacoucheobjet
Exemple814.Fonctionmembrestatique
classEntier
{
inti;
staticintj;
public:
staticintget_value(void);
};
intEntier::j=0;
intEntier::get_value(void)
{
j=1;
//Lgal.
returni;
//ERREUR!get_valuenepeutpasaccderi.
}
Lesfonctionsmembresstatiquessontsouventutilisesafinderegrouperuncertainnombredefonc
tionnalitsenrapportavecleurclasse.Ainsi,ellessontfacilementlocalisableetlesrisquesdeconflits
114
Chapitre8.C++:lacoucheobjet
denomsentredeuxfonctionsmembreshomonymessontrduits.
Nousverronsgalementdansle
Chapitre11commentviterlesconflitsdenomsglobauxdanslecadredesespacesdenommage.
8.11.Surchargedesoprateurs
Onavuprcdemmentquelesoprateursnesediffrencientdesfonctionsquesyntaxiquement,pas
logiquement.Dailleurs,lecompilateurtraiteunappelunoprateurcommeunappelunefonction.
LeC++permetdoncdesurchargerlesoprateurspourlesclassesdfiniesparlutilisateur,enutilisant
unesyntaxeparticulirecalquesurlasyntaxeutilisepourdfinirdesfonctionsmembresnormales.
Enfait,ilestmmepossibledesurchargerlesoprateursdulangagepourlesclassesdelutilisateur
endehorsdeladfinitiondecesclasses. LeC++disposedoncdedeuxmthodesdiffrentespour
surchargerlesoprateurs.
Lesseulsoprateursquinepeuventpastresurchargssontlessuivants:
::
.
.*
?:
sizeof
typeid
static_cast
dynamic_cast
const_cast
reinterpret_cast
Touslesautresoprateurssontsurchargeables.Leursurchargeneposegnralementpasdeproblme
etpeuttreralisesoitdanslaclassedesobjetssurlesquelsilssappliquent,
soitlextrieurde
cetteclasse.Cependant,uncertainnombredentreeuxdemandentdesexplicationscomplmentaires,
quelondonneralafindecettesection.
Note:Onprendragardeauxproblmesdeperformanceslorsdelasurchargedesoprateurs.
Si lafacilitdcrituredesexpressionsutilisantdesclassesestgrandementsimplifiegrcela
possibilitdesurchargerlesoprateurspourcesclasses,lesperformancesduprogrammepeu
vententregravementaffectes.Eneffet,lutilisationinconsidredesoprateurspeutconduire
ungrandnombredecopiesdesobjets,copiesquelonpourraitviterencrivantleprogramme
classiquement.Parexemple,laplupartdesoprateursrenvoientunobjetdutypedelaclassesur
laquelleilstravaillent.Cesobjetssontsouventcrslocalementdanslafonctiondeloprateur
(cestdirequilssont deporte auto). Parconsquent, cesobjetssont temporaireset sont
dtruitslasortiedelafonctiondeloprateur.Celaimposedoncaucompilateurdenfaireune
copiedanslavaleurderetourdelafonctionavantdensortir.Cettecopieseraellemmedtruite
parlecompilateurunefoisquelleauratutiliseparlinstructionqui aappellafonction. Si
lersultatdoittreaffectunobjetdelappelant,unedeuximecopieinutileestralisepar
rapport aucasoloprateuraurait travailldirectement danslavariablersultat. Si lesbons
compilateurssontcapablesdvitercescopies,celarestelexceptionetilvautmieuxtreaverti
lavancepluttquededevoirrcriretoutsonprogrammeaposterioripourdesproblmesde
performances.
115
Chapitre8.C++:lacoucheobjet
8.11.1.Surchargedesoprateursinternes
Unepremiremthodepoursurchargerlesoprateursconsistelesconsidrercommedesmthodes
normalesdelaclassesurlaquelleilssappliquent. Lenomdecesmthodesestdonnparlemot
cl operator,suivideloprateursurcharger.Letypedelafonctiondeloprateurestletypedu
rsultatdonnparlopration, etlesparamtres, donnsentreparenthses, sontlesoprandes. Les
oprateursdecetypesontappelsoprateursinternes,parcequilssontdclarslintrieurdela
classe.
Voicilasyntaxe:
typeoperatorOp(paramtres)
lcriture
AOpB
setraduisantpar:
A.operatorOp(B)
Aveccettesyntaxe,lepremieroprandeesttoujourslobjetauquelcettefonctionsapplique.Cette
maniredesurchargerlesoprateursestdoncparticulirementbienadaptepourlesoprateursqui
modifient lobjet surlequel ilstravaillent, commeparexemplelesoprateurs =, +=, ++, etc. Les
paramtresdelafonctionoprateursontalorsledeuximeoprandeetlessuivants.
Lesoprateursdfiniseninternedevrontsouventrenvoyerlobjetsurlequelilstravaillent(cenest
pasunencessitcependant).Celaestfaisablegrceaupointeur this.
Parexemple,laclassesuivanteimplmentelesnombrescomplexesavecquelquesunesdeleursop
rationsdebase.
Exemple816.Surchargedesoprateursinternes
classcomplexe
{
doublem_x,m_y;
//Lespartiesrellesetimaginaires.
public:
//Constructeursetoprateurdecopie:
complexe(doublex=0,doubley=0);
complexe(constcomplexe&);
complexe&operator=(constcomplexe&);
//Fonctionspermettantdelirelespartiesrelles
//etimaginaires:
doublere(void)const;
doubleim(void)const;
//Lesoprateursdebase:
complexe&operator+=(constcomplexe&);
complexe&operator=(constcomplexe&);
complexe&operator*=(constcomplexe&);
complexe&operator/=(constcomplexe&);
};
complexe::complexe(doublex,doubley)
116
Chapitre8.C++:lacoucheobjet
{
m_x=x;
m_y=y;
return;
}
complexe::complexe(constcomplexe&source)
{
m_x=source.m_x;
m_y=source.m_y;
return;
}
complexe&complexe::operator=(constcomplexe&source)
{
m_x=source.m_x;
m_y=source.m_y;
return*this;
}
doublecomplexe::re()const
{
returnm_x;
}
doublecomplexe::im()const
{
returnm_y;
}
complexe&complexe::operator+=(constcomplexe&c)
{
m_x+=c.m_x;
m_y+=c.m_y;
return*this;
}
complexe&complexe::operator=(constcomplexe&c)
{
m_x=c.m_x;
m_y=c.m_y;
return*this;
}
complexe&complexe::operator*=(constcomplexe&c)
{
doubletemp=m_x*c.m_xm_y*c.m_y;
m_y=m_x*c.m_y+m_y*c.m_x;
m_x=temp;
return*this;
}
complexe&complexe::operator/=(constcomplexe&c)
{
doublenorm=c.m_x*c.m_x+c.m_y*c.m_y;
doubletemp=(m_x*c.m_x+m_y*c.m_y)/norm;
m_y=(m_x*c.m_y+m_y*c.m_x)/norm;
117
Chapitre8.C++:lacoucheobjet
m_x=temp;
return*this;
}
Note: LabibliothquestandardC++fournit uneclassetraitant lesnombrescomplexesde
manirecomplte,laclassecomplex.Cetteclassenestdoncdonneiciqutitredexempleet
nedevravidemment pastreutilise. Ladfinitiondesnombrescomplexeset
deleur
principalespropritsseradonnedanslaSection14.3.1,olaclassecomplexseradcrite.
8.11.2.Surchargedesoprateursexternes
Unedeuximepossibilitnousestofferteparlelangagepoursurchargerlesoprateurs.Ladfinition
deloprateurnesefaitplusdanslaclassequilutilise,maisendehorsdecelleci,parsurchargedun
oprateurdelespacedenommageglobal.Ilsagitdoncdoprateursexternescettefois.
Lasurchargedesoprateursexternessefaitdoncexactementcommeonsurchargelesfonctionsnor
males.Danscecas,touslesoprandesdeloprateurdevronttrepasssenparamtres:ilnyaura
pasdeparamtreimplicite(lepointeur this nestpaspassenparamtre).
Lasyntaxeestlasuivante:
typeoperatorOp(oprandes)
o oprandes estlalistecompltedesoprandes.
Lavantagedecettesyntaxeest queloprateurest rellement symtrique, contrairement cequi
sepassepourlesoprateursdfinislintrieurdelaclasse. Ainsi, silutilisationdecetoprateur
ncessiteuntranstypagesurlundesoprandes,ilnestpasncessairequecetoprandesoitobliga
toirementledeuxime.Doncsilaclassedisposedeconstructeurspermettantdeconvertiruntypede
donneensonpropetype,cetypededonnepeuttreutilisavectouslesoprateursdelaclasse.
Parexemple,lesoprateursdaddition,desoustraction,demultiplicationetdedivisiondelaclasse
complexepeuventtreimplmentscommedanslexemplesuivant.
Exemple817.Surchargedoprateursexternes
classcomplexe
{
friendcomplexeoperator+(constcomplexe&,constcomplexe&);
friendcomplexeoperator(constcomplexe&,constcomplexe&);
friendcomplexeoperator*(constcomplexe&,constcomplexe&);
friendcomplexeoperator/(constcomplexe&,constcomplexe&);
doublem_x,m_y; //Lespartiesrellesetimaginaires.
public:
//Constructeursetoprateurdecopie:
118
Chapitre8.C++:lacoucheobjet
complexe(doublex=0,doubley=0);
complexe(constcomplexe&);
complexe&operator=(constcomplexe&);
//Fonctionspermettantdelirelespartiesrelles
//etimaginaires:
doublere(void)const;
doubleim(void)const;
//Lesoprateursdebase:
complexe&operator+=(constcomplexe&);
complexe&operator=(constcomplexe&);
complexe&operator*=(constcomplexe&);
complexe&operator/=(constcomplexe&);
};
//Lesoprateursdebaseonttludsici:
...
complexeoperator+(constcomplexe&c1,constcomplexe&c2)
{
complexeresult=c1;
returnresult+=c2;
}
complexeoperator(constcomplexe&c1,constcomplexe&c2)
{
complexeresult=c1;
returnresult=c2;
}
complexeoperator*(constcomplexe&c1,constcomplexe&c2)
{
complexeresult=c1;
returnresult*=c2;
}
complexeoperator/(constcomplexe&c1,constcomplexe&c2)
{
complexeresult=c1;
returnresult/=c2;
}
Aveccesdfinitions,ilestparfaitementpossibledeffectuerlamultiplicationdunobjetdetypecom
plexeavecunevaleurdetypedouble.Eneffet,cettevaleurseraautomatiquementconvertieencom
plexegrceauconstructeurdelaclassecomplexe,quiserautilisicicommeconstructeurdetransty
page.Unefoiscetteconversioneffectue,loprateuradquatestappliqu.
Onconstateraquelesoprateursexternesdoiventtredclarscommetantdesfonctionsamiesdela
classesurlaquelleilstravaillent,fautedequoiilsnepourraientpasmanipulerlesdonnesmembres
deleursoprandes.
Note:Certainscompilateurspeuvent supprimerlacrationdesvariablestemporaireslorsque
cellescisontutilisesentantquevaleurderetourdesfonctions.Celapermetdamliorergrande
mentlefficacitdesprogrammes,ensupprimanttouteslescopiesdobjetsinutiles.Cependant
cescompilateurssontrelativementraresetpeuventexigerunesyntaxeparticulirepoureffectuer
119
Chapitre8.C++:lacoucheobjet
cetteoptimisation.Gnralement,lescompilateursC++actuelssupprimentlacrationdevari
abletemporairedanslesretoursdefonctionssilavaleurderetourestconstruitedanslinstruction
return ellemme.Parexemple,loprateurdadditionpeuttreoptimisainsi:
complexeoperator+(constcomplexe&c1,constcomplexe&c2)
{
returncomplexe(c1.m_x+c2.m_x,c1.m_y+c2.m_y);
}
Cettecriturenestcependantpastoujoursutilisable,etloptimisationnestpasgarantie.
Lasyntaxedesoprateursexternespermetgalementdimplmenterlesoprateurspourlesquelsle
typedelavaleurderetourestceluideloprandedegaucheetqueletypedecetoprandenestpas
uneclassedfinieparlutilisateur(parexemplesicestuntypeprdfini).Eneffet,onnepeutpas
dfinirloprateurlintrieurdelaclassedupremieroprandedanscecas,puisquecetteclasseest
djdfinie.Demme,cettesyntaxepeuttreutiledanslecasdelcrituredoprateursoptimiss
pourcertainstypesdedonnes,pourlesquelslesoprationsralisesparloprateursontplussimples
quecellesquiauraientteffectuesaprstranstypage.
Parexemple,silonveutoptimiserlamultiplicationgaucheparunscalairepourlaclassecomplexe,
ondevraprocdercommesuit:
complexeoperator*(doublek,constcomplexe&c)
{
complexeresult(c.re()*k,c.im()*k);
returnresult;
}
cequipermettradcriredesexpressionsdutype:
complexec1,c2;
doubler;
...
c1=r*c2;
Lapremiresyntaxenauraitpermisdcrireunteloprateurquepourlamultiplicationdroitepar
undouble.Eneffet,pourcrireunoprateurinternepermettantderalisercetteoptimisation,ilaurait
fallusurchargerloprateurdemultiplicationdelaclassedoublepourluifaireaccepterunobjetde
typecomplexeensecondoprande...
8.11.3.Oprateursdaffectation
Nousavonsdjvuunexempledoprateurdaffectationaveclaclassecomplexecidessus.
Cet
oprateurtaittrssimple, maiscenestgnralementpastoujourslecas, etlimplmentationdes
oprateursdaffectationpeutparfoissouleverquelquesproblmes.
Premirement, commenous lavons dit dans laSection8.8.2, lefait dedfinir unoprateur
daffectationsignalesouventquelaclassenapasunestructuresimpleetque,
parconsquent, le
constructeurdecopieetledestructeurfournispardfautparlecompilateurnesuffisentpas.Ilfaut
doncveillerrespecterlargledestrois,quistipulequesilunedecesmthodesestredfinie,ilfaut
quelestroislesoient.Parexemple,sivousneredfinissezpasleconstructeurdecopie,lescritures
tellesque:
120
Chapitre8.C++:lacoucheobjet
classeobject=source;
Enfin,lacopiedesdonnespeutlanceruneexceptionetlaisserlobjetsurlequellaffectationsefait
dansuntatindtermin.Lasolutionlaplussimpledanscecasestencoredeconstruireunecopie
delobjetsourceenlocal,puisdchangerlecontenudesdonnesdelobjetaveccettecopie.Ainsi,
silacopiechouepouruneraisonouuneautre,lobjetsourcenestpasmodifietrestedansuntat
stable.Lepseudocodepermettantderaliserceciestlesuivant:
classe&classe::operator=(constclasse&source)
{
//Construitunecopietemporairedelasource:
classTemp(source);
//changelecontenudecettecopieaveclobjetcourant:
swap(Temp,*this);
//Renvoielobjetcourant(modifi)etdtruitlesdonnes
//delavariabletemporaire(contenantlesanciennesdonnes):
return*this;
}
121
Chapitre8.C++:lacoucheobjet
Note:Leproblmedeltat desobjetsnest passpcifiqueloprateurdaffectation, mais
touteslesmthodesqui modifientlobjet,donc,enpratique,touteslesmthodesnon const.
Lcrituredeclassessresauniveaudelagestiondeserreursestdoncrelativementdifficile.
VoustrouverezdeplusamplesinformationssurlemcanismedesexceptionsenC++dansle
Chapitre9.
8.11.4.Oprateursdetranstypage
NousavonsvudanslaSection8.8.3quelesconstructeurspeuventtreutilisspourconvertirdes
objetsdutypedeleurparamtreversletypedeleurclasse. Cesconversionspeuventavoirlieude
manireimpliciteounon,selonquelemotcl explicit estappliquauconstructeurenquestion.
Cependant, il nest pastoujoursfaisabledcrireuntel constructeur. Parexemple, laclassecible
peutparfaitementtreunedesclassesdelabibliothquestandard,dontonnedoitvidemmentpas
modifierlesfichierssource, oummeundestypesdebasedulangage,pourlequelilnyapasde
dfinition.Heureusement,lesconversionspeuventmalgrtouttreralisesdanscecas,simplement
ensurchargeantlesoprateursdetranstypage.
Prenonslexempledelaclassechaine,quipermetdefairedeschanesdecaractresdynamiques(de
longueurvariable).IlestpossibledelesconvertirenchaneCclassiques(cestdireentableaude
caractres)siloprateur (charconst*) atsurcharg:
chaine::operatorcharconst*(void)const;
Onconstateraquecetoprateurnattendaucunparamtre,puisquilsappliquelobjetquilappelle,
maissurtout il napasdetype. Eneffet, puisquecest unoprateurdetranstypage, sontypeest
ncessairementceluiquiluicorrespond(danslecasprsent,charconst*).
Note:Si unconstructeurdetranstypageestgalementdfinidanslaclassedutypecibledela
conversion,il peutexisterdeuxmoyensderaliserletranstypage.Danscecas,lecompilateur
choisiratoujoursleconstructeurdetranstypagedelaclasseciblelaplacedeloprateurde
transtypage,saufsilestdclar explicit .Cemotclpeutdonctreutilispartoutolonveut
viterquelecompilateurnutiliseleconstructeurdetranstypage.Cependant,cettetechniquene
fonctionnequaveclesconversionsimplicitesralisesparlecompilateur.Silutilisateureffectue
untranstypageexplicite,ceseranouveauleconstructeurquiseraappel.
Deplus,lesconversionsralisesparlintermdiairedunconstructeursontsouventplusperfor
mantesquecellesralisesparlintermdiairedunoprateurdetranstypage,enraisondufait
quelonviteainsilacopiedelavariabletemporairedansleretourdeloprateurdetranstypage.
Onviteradoncdedfinirlesoprateursdetranstypageautantquefairesepeut,etoncrirade
prfrencedesconstructeursdanslesclassesdestypesciblesdesconversionsralises.
8.11.5.Oprateursdecomparaison
Lesoprateursdecomparaisonsonttrssimplessurcharger.Laseulechoseessentielleretenirest
quilsrenvoientunevaleurboolenne. Ainsi, pourlaclassechaine, onpeutdclarerlesoprateurs
122
Chapitre8.C++:lacoucheobjet
dgalitetdinfriorit(danslordrelexicographiqueparexemple)dedeuxchanesdecaractres
commesuit:
boolchaine::operator==(constchaine&)const;
boolchaine::operator<(constchaine&)const;
8.11.6.Oprateursdincrmentationetdedcrmentation
Lesoprateursdincrmentationetdedcrmentationsonttouslesdeuxdoubles,cestdirequela
mmenotationreprsentedeuxoprateursenralit. Eneffet, ilsnontpaslammesignification,
selonquilssontplacsavantouaprsleuroprande.Leproblmeestquecommecesoprateursne
prennentpasdeparamtres(ilsnetravaillentquesurlobjet),ilestimpossibledelesdiffrencierpar
surcharge.Lasolutionquiatadopteestdelesdiffrencierendonnantunparamtrefictifdetype
intlundentreeux.Ainsi,lesoprateurs ++ et neprennentpasdeparamtrelorsquilsagitdes
oprateursprfixs,etontunargumentfictif(quelonnedoitpasutiliser)lorsquilssontsuffixs.Les
versionsprfixesdesoprateursdoiventrenvoyerunerfrencesurlobjetluimme, lesversions
suffixesenrevanchepeuventsecontenterderenvoyerlavaleurdelobjet.
Exemple818.Oprateursdincrmentationetdedcrmentation
classEntier
{
inti;
public:
Entier(intj)
{
i=j;
return;
}
Entieroperator++(int)
{
Entiertmp(i);
++i;
returntmp;
}
//Oprateursuffixe:
//retournelavaleuretincrmente
//lavariable.
Entier&operator++(void)//Oprateurprfixe:incrmente
{
//lavariableetlaretourne.
++i;
return*this;
}
};
Note:Lesoprateurssuffixscrant desobjetstemporaires, ilspeuvent nuiregravement aux
performancesdesprogrammesquilesutilisentdemanireinconsidre.Parconsquent,onne
lesutiliseraquelorsquecelaest rellement ncessaire. Enparticulier, onviteradutiliserces
oprateursdanstouteslesoprationsdincrmentationdesbouclesditration.
123
Chapitre8.C++:lacoucheobjet
8.11.7.Oprateurfonctionnel
Loprateurdappeldefonctions () peutgalementtresurcharg.Cetoprateurpermetderaliser
desobjetsquisecomportentcommedesfonctions(cequelonappelledesfoncteurs).Labibliothque
standardC++enfaitunusageintensif,commenouspourronsleconstaterdansladeuximepartiede
cedocument.
Loprateurfonctionnelestgalementtrsutileenraisondesonnarit(*, /,etc.sontdesoprateurs
binairescarilsontdeuxoprandes, ?: estunoprateurternairecarilatroisoprandes, () estnaire
carilpeutavoirnoprandes).Ilestdoncutiliscourammentpourlesclassesdegestiondematrices
denombres,afindautoriserlcriture matrice(i,j,k) .
Exemple819.Implmentationduneclassematrice
classmatrice
{
typedefdouble*ligne;
ligne*lignes;
unsignedshortintn;
unsignedshortintm;
//Nombredelignes(1erparamtre).
//Nombredecolonnes(2meparamtre).
public:
matrice(unsignedshortintnl,unsignedshortintnc);
matrice(constmatrice&source);
~matrice(void);
matrice&operator=(constmatrice&m1);
double&operator()(unsignedshortinti,unsignedshortintj);
doubleoperator()(unsignedshortinti,unsignedshortintj)const;
};
//Leconstructeur:
matrice::matrice(unsignedshortintnl,unsignedshortintnc)
{
n=nl;
m=nc;
lignes=newligne[n];
for(unsignedshortinti=0;i<n;++i)
lignes[i]=newdouble[m];
return;
}
//Leconstructeurdecopie:
matrice::matrice(constmatrice&source)
{
m=source.m;
n=source.n;
lignes=newligne[n];
//Alloue.
for(unsignedshortinti=0;i<n;++i)
{
lignes[i]=newdouble[m];
for(unsignedshortintj=0;j
<m;++j) //Copie.
lignes[i][j]=source.lignes[i][j];
}
return;
}
//Ledestructeur:
124
Chapitre8.C++:lacoucheobjet
matrice::~matrice(void)
{
for(unsignedshortinti=0;i <n;++i)
delete[]lignes[i];
delete[]lignes;
return;
}
//Loprateurdaffectation:
matrice&matrice::operator=(constmatrice&source)
{
if(&source!=this)
{
if(source.n!=n||source.m!=m)
//Vrifielesdimensions.
{
for(unsignedshortinti=0;i
<n;++i)
delete[]lignes[i];
delete[]lignes;
//Dtruit...
m=source.m;
n=source.n;
lignes=newligne[n];
//etralloue.
for(i=0;i <n;++i)lignes[i]=newdouble[m];
}
for(unsignedshortinti=0;i
<n;++i)//Copie.
for(unsignedshortintj=0;j
<m;++j)
lignes[i][j]=source.lignes[i][j];
}
return*this;
}
//Oprateursdaccs:
double&matrice::operator()(unsignedshortinti,
unsignedshortintj)
{
returnlignes[i][j];
}
doublematrice::operator()(unsignedshortinti,
unsignedshortintj)const
{
returnlignes[i][j];
}
Ainsi,onpourraeffectuerladclarationdunematriceavec:
matricem(2,3);
etaccderseslmentssimplementavec:
m(i,j)=6;
Onremarqueraquelonadfinideuxoprateursfonctionnelsdanslexempledonncidessus. Le
premierrenvoieunerfrenceetpermetdemodifierlavaleurdundeslmentsdelamatrice.Cet
oprateurnepeutbienentendupassappliquerunematriceconstante,mmesimplementpourlire
125
Chapitre8.C++:lacoucheobjet
unlment. Cest doncledeuximeoprateurqui serautilispourlireleslmentsdesmatrices
constantes,carilrenvoieunevaleuretnonplusunerfrence.Lechoixdeloprateurutiliserest
dterminparlaprsencedumotcl const,quiindiquequeseulcetoprateurpeuttreutilispour
unematriceconstante.
Note:Lesoprationsdebasesurlesmatrices(addition,soustraction,inversion,transposition,
etc.)nontpastreportesici parsouci declart.Lamanirededfinircesoprateursat
prsentedanslessectionsprcdentes.
8.11.8.Oprateursdindirectionetdedrfrencement
Loprateurdedrfrencement* permetlcrituredeclassesdontlesobjetspeuventtreutilissdans
desexpressionsmanipulantdespointeurs.Loprateurdindirection& quantlui,permetderenvoyer
uneadresseautrequecelledelobjetsurlequelilsapplique.Enfin,loprateurdedrfrencement
etdeslectiondemembresdestructures > permetderaliserdesclassesquiencapsulentdautres
classes.
Si lesoprateursdedrfrencement et dindirection & et * peuvent renvoyerunevaleurdetype
quelconque,cenestpaslecasdeloprateurdedrfrencementetdeslectiondemembre >.Cet
oprateurdoitncessairementrenvoyeruntypepourlequelildoitencoretreapplicable.Cetypedoit
doncsoitsurchargerloprateur >,soittreunpointeursurunestructure,unionouclasse.
Exemple820.Oprateurdedrfrencementetdindirection
//Cetteclasseestencapsuleparuneautreclasse:
structEncapsulee
{
inti;
//Donneaccder.
};
Encapsuleeo;
//Objetmanipuler.
//Cetteclasseestlaclasseencapsulante:
structEncapsulante
{
Encapsulee*operator>(void)const
{
return&o;
}
Encapsulee*operator&(void)const
{
return&o;
}
Encapsulee&operator*(void)const
{
returno;
}
};
//Exempledutilisation:
voidf(inti)
126
Chapitre8.C++:lacoucheobjet
{
Encapsulantee;
e>i=2;
//Enregistre2danso.i.
(*e).i=3;
//Enregistre3danso.i.
Encapsulee*p=&e;
p>i=4;
//Enregistre4danso.i.
return;
}
8.11.9.Oprateursdallocationdynamiquedemmoire
Lesoprateurslesplusdifficilescriresontsansdoutelesoprateursdallocationdynamiquede
mmoire.Cesoprateursprennentunnombrevariabledeparamtres,parcequilssontcompltement
surchargeables(cestdirequilestpossiblededfinirplusieurssurchargesdecesoprateursmme
auseindunemmeclasse, silssont dfinisdemanireinterne). Il est doncpossiblededfinir
plusieursoprateurs new ou new[], etplusieursoprateurs delete ou delete[]. Cependant, les
premiersparamtresdecesoprateursdoiventtoujourstrelatailledelazonedelammoireallouer
danslecasdesoprateurs new et new[],etlepointeursurlazonedelammoirerestituerdansle
casdesoprateurs delete et delete[].
Laformelaplussimplede new neprendquunparamtre:lenombredoctetsallouer, quivaut
toujourslatailledelobjetconstruire.Ildoitrenvoyerunpointeurdutypevoid.Loprateur delete
correspondant peut prendre, quant lui, soit un, soit deuxparamtres. Commeonladjdit, le
premierparamtreesttoujoursunpointeurdutypevoidsurlobjetdtruire.Ledeuximeparamtre,
silexiste,estdutypesize_tetcontientlatailledelobjetdtruire.Lesmmesrglessappliquent
pourlesoprateurs new[] et delete[],utilisspourlestableaux.
Lorsquelesoprateurs delete et delete[] prennentdeuxparamtres,ledeuximeparamtreest
latailledelazonedelammoirerestituer.Celasignifiequelecompilateursechargedemmoriser
cetteinformation.Pourlesoprateurs new et delete,celanecausepasdeproblme,puisquelataille
decettezoneestfixeparletypedelobjet.Enrevanche,pourlestableaux,latailledutableaudoit
trestockeavecletableau.Engnral,lecompilateurutiliseunenttedevantletableaudobjets.
Cestpourcelaquelatailleallouerpasse new[],quiestlammequelatailledsallouerpasse
enparamtre delete[],nestpasgalelatailledunobjetmultiplieparlenombredobjetsdu
tableau.Lecompilateurdemandeunpeuplusdemmoire,pourmmoriserlatailledutableau.On
nepeutdoncpas,danscecas,fairedhypothsesquantlastructurequelecompilateurdonnerala
mmoireallouepourstockerletableau.
Enrevanche,si delete[] neprendenparamtrequelepointeursurletableau,lammorisationdela
new[] lavaleur
tailledutableauestlachargeduprogrammeur.Danscecas,lecompilateurdonne
exactedelatailledutableau,savoirlatailledunobjetmultiplieparlenombredobjetsdansle
tableau.
Exemple821.Dterminationdelatailledelenttedestableaux
#include <stdio.h>
intbuffer[256];
//Bufferservantstockerletableau.
classTemp
{
chari[13];
//sizeof(Temp)doittrepremier.
public:
127
Chapitre8.C++:lacoucheobjet
staticvoid*operatornew[](size_ttaille)
{
returnbuffer;
}
staticvoidoperatordelete[](void*p,size_ttaille)
{
printf("Tailledelentte:%d\n",
taille(taille/sizeof(Temp))*sizeof(Temp));
return;
}
};
intmain(void)
{
delete[]newTemp[1];
return0;
}
Lesparamtressontdoncpasssentreparenthsescommepourunefonctionnormale.Lenomdela
fonctionest new,etlenomdelaclassesuitlexpressionnew commedanslasyntaxesansparamtres.
Cetteutilisationde new estappelenewavecplacement.
Leplacementestsouventutilisafinderaliserdesrallocationsdemmoiredunobjetunautre.
Parexemple,silondoitdtruireunobjetalloudynamiquementetenreconstruireimmdiatement
unautredummetype,lesoprationssuivantessedroulent:
1.appeldudestructeurdelobjet(ralisparlexpression delete);
2.appeldeloprateur delete ;
3.appeldeloprateur new ;
4.appelduconstructeurdunouvelobjet(ralisparlexpression new).
128
Chapitre8.C++:lacoucheobjet
Celanestpastrsefficace,puisquelammoireestrestituepourtreallouedenouveauimmdiate
mentaprs.Ilestbeaucouppluslogiquederutiliserlammoiredelobjetdtruirepourlenouvel
objet,etdereconstruirecedernierdanscettemmoire.Celapeutsefairecommesuit:
1.appelexplicitedudestructeurdelobjetdtruire;
2.appelde new aveccommeparamtresupplmentairelepointeursurlobjetdtruit;
3.appelduconstructeurdudeuximeobjet(ralisparlexpression new).
Lappelde new nefaitalorsaucuneallocation:ongagneainsibeaucoupdetemps.
Exemple822.Oprateursnewavecplacement
#include <stdlib.h>
classA
{
public:
A(void)
{
return;
}
~A(void)
{
return;
}
//Constructeur.
//Destructeur.
//Loprateurnewsuivantutiliseleplacement.
//Ilreoitenparamtrelepointeursurlebloc
//utiliserpourlarequtedallocationdynamique
//demmoire.
staticvoid*operatornew(size_ttaille,A*bloc)
{
return(void*)bloc;
}
//Oprateurnewnormal:
staticvoid*operatornew(size_ttaille)
{
//Implmentation:
returnmalloc(taille);
}
//Oprateurdeletenormal:
staticvoidoperatordelete(void*pBlock)
{
free(pBlock);
return;
}
};
intmain(void)
{
129
Chapitre8.C++:lacoucheobjet
A*pA=newA;
pA>~A();
A*pB=new(pA)A;
deletepB;
return0;
//CrationdunobjetdeclasseA.
//LoprateurnewglobalduC++estutilis.
//AppelexplicitedudestructeurdeA.
//RutilisationdelammoiredeA.
//Destructiondelobjet.
130
Chapitre8.C++:lacoucheobjet
return;
}
~A(void)
{
return;
}
//Destructeur.
//Loprateurnewsuivantutiliseleplacement.
//Ilreoitenparamtrelepointeursurlebloc
//utiliserpourlarequtedallocationdynamique
//demmoire.
staticvoid*operatornew(size_ttaille,A*bloc)
{
return(void*)bloc;
}
//Loprateurdeletesuivantestutilisdanslesexpressions
//quiutilisentloprateurnewavecplacementcidessus,
//siuneexceptionseproduitdansleconstructeur.
staticvoidoperatordelete(void*p,A*bloc)
{
//Onnefaitrien,parcequeloprateurnewcorrespondant
//napasalloudemmoire.
return;
}
//Oprateurnewetdeletenormaux:
staticvoid*operatornew(size_ttaille)
{
returnmalloc(taille);
}
staticvoidoperatordelete(void*pBlock)
{
free(pBlock);
return;
}
};
intmain(void)
{
A*pA=newA;
pA>~A();
bThrow=true;
//CrationdunobjetdeclasseA.
//AppelexplicitedudestructeurdeA.
//Maintenant,leconstructeurdeAlance
//uneexception.
try
{
A*pB=new(pA)A;
//RutilisationdelammoiredeA.
//Siuneexceptionalieu,loprateur
//delete(void*,A*)avecplacement
//estutilis.
//Destructiondelobjet.
deletepB;
}
catch(...)
{
//Loprateurdelete(void*,A*)nelibrepaslammoire
131
Chapitre8.C++:lacoucheobjet
//allouelorsdupremiernew.Ilfautdoncquandmme
//lefaire,maissansdelete,carlobjetpointparpA
//estdjdtruit,etceluipointparpBlatpar
//loprateurdelete(void*,A*):
free(pA);
}
return0;
}
std::.Si
Note:Commesonnomlindique,cetteclasseestdfiniedanslespacedenommage
vousnevoulezpasutiliserlesnotionsdesespacesdenommage,vousdevrezinclurelefichier
dentte new.h aulieude new.Vousobtiendrezdeplusamplesrenseignementssurlesespaces
denommagedansleChapitre11.
La classe exceptiondont bad_alloc hrite est dclare comme suit dans le fichier dentte
exception :
classexception
{
132
Chapitre8.C++:lacoucheobjet
public:
exception(void)throw();
exception(constexception&)throw();
exception&operator=(constexception&)throw();
virtual~exception(void)throw();
virtualconstchar*what(void)constthrow();
};
Note:VoustrouverezplusdinformationssurlesexceptionsdansleChapitre9.
Si vous dsirez remplacer le gestionnaire par dfaut, vous pouvez utiliser la fonction
std::set_new_handler. Cettefonctionattendenparamtrelepointeur
sur legestionnaire
derreur installer et renvoielepointeur sur legestionnairederreur prcdemment install.
Les gestionnaires derreurs neprennent aucunparamtreet nerenvoient aucunevaleur. Leur
comportementdoittrelesuivant:
soitilsprennentlesmesuresncessairespourpermettrelallocationdublocdemmoiredemand
etrendentlamainloprateur new.Cedernierrefaitalorsunetentativepourallouerleblocde
mmoire.Sicettetentativechouenouveau,legestionnairederreurestrappel.Cettebouclese
poursuitjusqucequeloprationsedroulecorrectementouquuneexceptionstd::bad_allocsoit
lance;
soitilslancentuneexceptiondeclassestd::bad_alloc;
soitilsterminentlexcutionduprogrammeencours.
new et new[],quiren
Labibliothquestandarddfinituneversionavecplacementdesoprateurs
voientlepointeurnulaulieudelanceruneexceptionencasdemanquedemmoire.Cesoprateurs
prennentundeuximeparamtre, detypestd::nothrow_t, quidoittrespcifilorsdelappel. La
bibliothquestandarddfinitunobjetconstantdecetypeafinquelesprogrammespuissentlutiliser
sansavoirledfinireuxmme.Cetobjetsenomme std::nothrow
Exemple823.Utilisationdenewsansexception
char*data=new(std::nothrow)char[25];
if(data==NULL)
{
//Traitementdelerreur...
.
.
.
}
Note:LaplupartdescompilateursnerespectentpaslesrglesdictesparlanormeC++.En
effet, ilsprfrent retournerlavaleurnulleencasdemanquedemmoireaulieudelancer
uneexception.Onpeutrendrecesimplmentationscompatiblesaveclanormeeninstallantun
gestionnairederreurquilanceluimmelexceptionstd::bad_alloc.
133
Chapitre8.C++:lacoucheobjet
8.12.Desentressortiessimplifies
Lesfluxdentre/sortiedelabibliothquestandardC++constituentsansdoutelunedesapplications
lesplusintressantesdelasurchargedesoprateurs. Commenousallonslevoir, lasurchargedes
oprateurs << et >> permetdcrireetdeliresurcesfluxdemaniretrsintuitive.
Eneffet,labibliothquestandardC++dfinitdanslentteiostream desclassesextrmementpuis
santespermettantdemanipulerlesfluxdentre/sortie.Cesclassesralisentenparticulierlesop
rationsdentre/sortiedeetverslespriphriquesdentreetlespriphriquesdesortiestandards
(gnralement, leclavieretlcran), maisellesnesarrtentpasl:ellespermettentgalementde
travaillersurdesfichiersouencoresurdestamponsenmmoire.
Lesclassesdentre/sortiedelabibliothquestandardC++permettentdoncdeffectuerlesmmes
oprationsquelesfonctions printf et scanf delabibliothqueCstandard. Cependant, grceau
mcanismedesurchargedesoprateurs, ellessontbeaucoupplusfacilesdutilisation. Eneffet, les
oprateurs << et >> decesclassesont tsurchargspourchaquetypededonnedulangage,
permettant ainsi deraliserdesentres/ sortiestypesextrmement facilement. Loprateur <<,
galementappeleoprateurdinsertion,serautilispourraliserdescrituressurunfluxdedonnes,
tandisqueloprateur >>,ouoprateurdextraction,permettraderaliserlalecturedunenouvelle
donnedanslefluxdentre.Cesdeuxoprateursrenvoienttouslesdeuxlefluxdedonnesutilis,
cequipermetderaliserplusieursoprationsdentre/sortiesuccessivementsurlemmeflux.
Note:Cettesectionnapaspourbutdedcrireendtail lesfluxdentre/sortiedelabiblio
thquestandardC++, maisplutt denfaireuneprsentationsimplepermettant delesutiliser
sansavoirseplongerprmaturmentdansdesnotionsextrmementvolues.Voustrouverez
unedescriptionexhaustivedesmcanismesdesfluxdentre/sortiedelabibliothquestandard
C++dansleChapitre15.
Labibliothquestandarddfinitquatreinstancesparticuliresdesesclassesdentre/sortie: cin,
cout, cerr et clog.Cesobjetssontdesinstancesdesclassesistreametostream,prenantrespecti
vementenchargelentreetlasortiedesdonnesdesprogrammes.Lobjet cin correspondauflux
dentrestandard stdin duprogramme, et lobjet cout auxfluxdesortiestandard stdout. En
fin,lesobjets cerr et clog sontassocisaufluxderreursstandard stderr.Thoriquement, cerr
doittreutilispourlcrituredesmessagesderreurdesprogrammes, et clog pourlesmessages
dinformation.Cependant,enpratique,lesdonnescritessurcesdeuxfluxsontcritesdanslemme
flux,etlemploidelobjet clog estassezrare.
Lutilisationdesoprateursdinsertionet
suivante:
dextractionsur cesfluxsersumedonclasyntaxe
Commeonlevoit,ilestpossibledeffectuerplusieursentresouplusieurssortiesuccessivementsur
unmmeflux.
Deplus,labibliothquestandarddfiniecequelonappelledesmanipulateurspermettantderaliser
desoprationssimplessurlesfluxdentre/sortie.Lemanipulateurleplusutilisestsansnuldoute
lemanipulateur endl qui,commesonnomlindique,permetdesignalerunefindeligneetdeffectuer
unsautdelignelorsquilestemploysurunfluxdesortie.
Exemple824.Fluxdentre/sortiecinetcout
#include <iostream>
134
Chapitre8.C++:lacoucheobjet
usingnamespacestd;
intmain(void)
{
inti;
//Litunentier:
cin >> i;
//Affichecetentieretlesuivant:
cout << i << "" << i+1 << endl;
return0;
}
Note:CommeonleverradansleChapitre15,lesmanipulateurssontenralitdesfonctions
pour letypedesquellesunoprateur << ouunoprateur >> atdfini danslesclasses
dentre/ sortie.Cesoprateursappellent cesfonctions, qui effectuent chacunedesmodifica
tionsspcifiquessurlefluxsurlequelellestravaillent.
Lesfluxdentre/sortiecin, coutcerret clog sontdclarsdanslespacedenommagestd::
delabibliothquestandardC++.Ondevradoncfaireprcderleurnomduprfixe std:: pour
yaccder,ouutiliserundirective using pourimporterlessymbolesdelabibliothquestandard
C++danslespacedenommageglobal.Voustrouverezdeplusamplesrenseignementssurles
espacesdenommagesdansleChapitre11.
LesavantagesdesfluxC++sontnombreux,onnoteraenparticulierceuxci:
letypedesdonneestautomatiquementprisencompteparlesoprateursdinsertionetdextraction
(ilssontsurchargspourtouslestypesprdfinis);
lesoprateursdextractiontravaillentparrfrence(onnerisqueplusdomettreloprateur&dans
lafonction scanf);
ilestpossiblededfinirdesoprateursdinsertionetdextractionpourdautrestypesdedonnes
quelestypesdebasedulangage;
leurutilisationestglobalementplussimple.
Lesfluxdentre/sortiedfinisparlabibliothqueC++sontdoncduneextrmesouplesseetsont
extensiblesauxtypesdedonnesutilisateur.Parailleurs,ilsdisposentdungrandnombredepara
mtresdeformatageetdoptionsavances.ToutescesfonctionnalitsserontdcritesdansleChapitre
15,onousverronsgalementcommentraliserdesentres/sortiesdansdesfichiers.
8.13.Mthodesvirtuelles
Lesmthodesvirtuellesnontstrictementrienvoiraveclesclassesvirtuelles,bienquellesutilisent
lemmemotcl virtual.Cemotclestutilisicidansuncontexteetdansunsensdiffrent.
Noussavonsquilestpossiblederedfinirlesmthodesduneclassemredansuneclassefille.Lors
delappeldunefonctionainsiredfinie,lafonctionappeleestladernirefonctiondfiniedansla
hirarchiedeclasse. Pourappelerlafonctiondelaclassemrealorsquelleatredfinie, ilfaut
prciserlenomdelaclasselaquelleelleappartientavecloprateurdersolutiondeporte( ::).
135
Chapitre8.C++:lacoucheobjet
Bienquesimple,cetteutilisationdelaredfinitiondesmthodespeutposerdesproblmes.Supposons
quuneclasseBhritedesaclassemreA.SiApossdeunemthode x appelantuneautremthode y
redfiniedanslaclassefilleB,quesepassetillorsquunobjetdeclasseBappellelamthode x ?La
mthodeappeletantcelledelaclasseA,elleappelleralamthodey delaclasseA.Parconsquent,
laredfinitionde y nesertriendsquonlappellepartirdunedesfonctionsdunedesclasses
mres.
Unepremiresolutionconsisteraitredfinirlamthode x danslaclasseB.Maiscenestnilgant,
x delaclasse
niefficace.Ilfautenfaitforcerlecompilateurnepasfaireleliendanslafonction
Aaveclafonction y delaclasseA. Ilfautque x appellesoitlafonction y delaclasseAsielle
estappeleparunobjetdelaclasseA,soitlafonction y delaclasseBsielleestappelepourun
objetdelaclasseB.Lelienaveclunedesmthodes y nedoittrefaitquaumomentdelexcution,
cestdirequondoitfaireuneditiondeliensdynamique.
LeC++permetdefairecela.Pourcela,ilsuffitdedclarervirtuellelafonctiondelaclassedebase
quiestredfiniedanslaclassefille,cestdirelafonction y.Celasefaitenfaisantprcderparle
motcl virtual danslaclassedebase.
Exemple825.Redfinitiondemthodedeclassedebase
#include <iostream>
usingnamespacestd;
//Dfinitlaclassedebasedesdonnes.
classDonneeBase
{
protected:
intNumero;
intValeur;
//Lesdonnessontnumrotes.
//etsontconstituesdunevaleurentire
//pourlesdonnesdebase.
public:
voidEntre(void);
voidMiseAJour(void);
};
//Entreunedonne.
//Metjourladonne.
voidDonneeBase::Entre(void)
{
cin >> Numero;
//Entrelenumrodeladonne.
cout << endl;
cin >> Valeur;
//Entresavaleur.
cout << endl;
return;
}
voidDonneeBase::MiseAJour(void)
{
Entre();
//Entreunenouvelledonne
//laplacedeladonneencours.
return;
}
/*Dfinitlaclassedesdonnesdtailles.*/
classDonneeDetaillee:privateDonneeBase
{
136
Chapitre8.C++:lacoucheobjet
intValeurEtendue;
public:
voidEntre(void);
};
//Lesdonnesdtaillesontenplus
//unevaleurtendue.
//Redfinitiondelamthodedentre.
voidDonneeDetaillee::Entre(void)
{
DonneeBase::Entre();
//Appellelamthodedebase.
cin >> ValeurEtendue; //Entrelavaleurtendue.
cout << endl;
return;
}
//Fonctionvirtuelle.
8.14.Drivation
Nousallonsvoiricilesrglesdedrivation.Cesrglespermettentdesavoircequiestautorisetce
quinelestpaslorsquontravailleavecdesclassesdebaseetleursclassesfilles(ouclassesdrives).
Lapremirergle, quiestaussilaplussimple, indiquequilestpossibledutiliserunobjetdune
classedrivepartout olonpeut utiliserunobjet dunedesesclassesmres. Lesmthodeset
137
Chapitre8.C++:lacoucheobjet
donnesdesclassesmresappartiennenteneffetparhritageauxclassesfilles.Bienentendu,ondoit
avoirlesdroitsdaccssurlesmembresdelaclassedebasequelonutilise(laccspeuttrerestreint
lorsdelhritage).
Ladeuximergleindiquequilestpossibledefaireuneaffectationduneclassedriveversune
classemre.Lesdonnesquineserventpaslinitialisationsontperdues,puisquelaclassemrene
possdepasleschampscorrespondants.Enrevanche,linverseeststrictementinterdit.Eneffet,les
donnesdelaclassefillequinexistentpasdanslaclassemrenepourraientpasrecevoirdevaleur,
etlinitialisationneseferaitpascorrectement.
Enfin,latroisimergleditquelespointeursdesclassesdrivessontcompatiblesaveclespointeurs
desclassesmres.Celasignifiequilestpossibledaffecterunpointeurdeclassedriveunpointeur
dunedesesclassesdebase.Ilfautbienentenduquelonaitenoutreledroitdaccderlaclasse
debase, cestdirequaumoinsundesesmembrespuissetreutilis.
Cetteconditionnestpas
private
toujoursvrifie,enparticulierpourlesclassesdebasedontlhritageest
.
Unobjetdrivpointparunpointeurdunedesclassesmresdesaclasseestconsidrcommeun
objetdelaclassedupointeurquilepointe.Lesdonnesspcifiquessaclassenesontpassupprimes,
ellessontseulementmomentanmentinaccessibles.Cependant,lemcanismedesmthodesvirtuelles
continuedefonctionnercorrectement. Enparticulier, ledestructeurdelaclassedebasedoit tre
dclarentantquemthodevirtuelle.Celapermetdappelerlebondestructeurencasdedestruction
delobjet.
Ilestpossibledeconvertirunpointeurdeclassedebaseenunpointeurdeclassedrivesilaclasse
debasenestpasvirtuelle. Cependant, mmelorsquelaclassedebasenestpasvirtuelle, celaest
dangereux, carlaclassedrivepeutavoirdesmembresquinesontpasprsentsdanslaclassede
base, etlutilisationdecepointeurpeutconduiredeserreurstrsgraves.
Cestpourcetteraison
quuntranstypageestncessairepourcetypedeconversion.
Soientparexemplelesdeuxclassesdfiniescommesuit:
#include <iostream>
usingnamespacestd;
classMere
{
public:
Mere(void);
~Mere(void);
};
Mere::Mere(void)
{
cout << "Constructeurdelaclassemre."<< endl;
return;
}
Mere::~Mere(void)
{
cout << "Destructeurdelaclassemre."<< endl;
return;
}
classFille:publicMere
{
public:
138
Chapitre8.C++:lacoucheobjet
Fille(void);
~Fille(void);
};
Fille::Fille(void):Mere()
{
cout << "Constructeurdelaclassefille."<< endl;
return;
}
Fille::~Fille(void)
{
cout << "Destructeurdelaclassefille."<< endl;
return;
}
Aveccesdfinitions,seulelapremiredesdeuxaffectationssuivantesestautorise:
Merem;
Fillef;
//Instanciationdedeuxobjets.
m=f;
f=m;
//Celaestautoris,maislinverseneleseraitpas:
//ERREUR!!(necompilepas).
Lesmmesrglessontapplicablespourlespointeursdobjets:
Mere*pm,m;
Fille*pf,f;
pf=&f;
//Autoris.
pm=pf;
//Autoris.Lesdonnesetlesmthodes
//delaclassefillenesontplusaccessibles
//aveccepointeur:*pmestunobjet
//delaclassemre.
pf=&m;
//ILLGAL:ilfautfaireuntranstypage:
pf=(Fille*)&m; //Cettefois,cestlgal,maisDANGEREUX!
//Eneffet,lesmthodesdelaclassefilles
//nesontpasdfinies,puisquemestuneclassemre.
Lutilisationdunpointeursurlaclassedebasepouraccderuneclassedrivencessitedutiliser
desmthodesvirtuelles. Enparticulier, il est ncessairederendrevirtuelslesdestructeurs.
Par
exemple,avecladfinitiondonnecidessuspourlesdeuxclasses,lecodesuivantestfaux:
Mere*pm;
Fille*pf=newFille;
pm=pf;
deletepm;//Appeldudestructeurdelaclassemre!
Pourrsoudreleproblme, ilfautqueledestructeurdelaclassemresoitvirtuel(ilestinutilede
dclarervirtuelledestructeurdesclassesfilles):
139
Chapitre8.C++:lacoucheobjet
classMere
{
public:
Mere(void);
virtual~Mere(void);
};
8.15.MthodesvirtuellespuresClassesabstraites
Unemthodevirtuellepureestunemthodequiestdclaremaisnondfiniedansuneclasse.Elle
estdfiniedansunedesclassesdrivesdecetteclasse.
Uneclasseabstraiteestuneclassecomportantaumoinsunemthodevirtuellepure.
tantdonnquelesclassesabstraitesontdesmthodesnondfinies,ilestimpossibledinstancierdes
objetspourcesclasses.Enrevanche,onpourralesrfrenceravecdespointeurs.
Lemcanismedesmthodesvirtuellespuresetdesclassesabstraitespermetdecrerdesclassesde
basecontenanttouteslescaractristiquesdunensembledeclassesdrives,pourpouvoirlesmanipu
leravecununiquetypedepointeur.Eneffet,lespointeursdesclassesdrivessontcompatiblesavec
lespointeursdesclassesdebase,onpourradoncrfrencerlesclassesdrivesavecdespointeurs
surlesclassesdebase,doncavecununiquetypesousjacent:celuidelaclassedebase.Cependant,
lesmthodesdesclassesdrivesdoiventexisterdanslaclassedebasepourpouvoirtreaccessibles
traverslepointeursurlaclassedebase. Cesticiquelesmthodesvirtuellespuresapparaissent.
Ellesformentunmoulepourlesmthodesdesclassesdrives,quilesdfinissent.Bienentendu,il
fautquecesmthodessoientdclaresvirtuelles,puisquelaccssefaitavecunpointeurdeclassede
baseetquilfautquecesoitlamthodedelaclasserelledelobjet(cestdirelaclassedrive)
quisoitappele.
Pourdclarerunemthodevirtuellepuredansuneclasse, ilsuffitdefairesuivresadclarationde
=0 .Lafonctiondoitgalementtredclarevirtuelle:
virtualtypenom(paramtres)=0;
=0 signifieicisimplementquilnyapasdimplmentationdecettemthodedanscetteclasse.
Note: =0 doittreplaccompltementenfindedclaration,cestdireaprslemotcl const
pourlesmthodes const et aprsladclarationdelalistedesexceptionsautorises(voirle
Chapitre9pourplusdedtailscesujet).
Unexemplevautmieuxquunlongdiscours.Soitdonc,parexemple,construireunestructurede
donnespouvantcontenirdautresstructuresdedonnes,quelsquesoientleurstypes.Cettestructure
dedonnesestappeleunconteneur,parcequellecontientdautresstructuresdedonnes.Ilestpos
140
Chapitre8.C++:lacoucheobjet
siblededfinirdiffrentstypesdeconteneurs.Danscetexemple,onnesintresseraquauconteneur
detypesac.
Unsacestunconteneurpouvantcontenirzroouplusieursobjets,chaqueobjetntantpasforcment
unique. Unobjetpeutdonctreplacplusieursfoisdanslesac. Unsacdisposededeuxfonctions
permettantdymettreetdenretirerunobjet.Ilaaussiunefonctionpermettantdediresiunobjetse
trouvedanslesac.
Nousallonsdclareruneclasseabstraitequiserviradeclassedebasepourtouslesobjetsutilisables.
Lesacnemanipuleraquedespointeurssurlaclasseabstraite,cequipermettrasonutilisationpour
touteclassedrivantdecetteclasse.Afindediffrencierdeuxobjetsgaux,unnumrouniquedevra
treattribuchaqueobjetmanipul. Lechoixdecenumroestlachargedesobjets, laclasse
abstraitedontilsdriventdevradoncavoirunemthoderenvoyantcenumro.
Lesobjetsdevront
touspouvoirtreaffichsdansunformatquileurestpropre. Lafonctionutiliserpourcelasera
print.Cettefonctionseraunemthodevirtuellepuredelaclasseabstraite,puisquelledevratre
dfiniepourchaqueobjet.
Passonsmaintenantauprogramme...
Exemple826.Conteneurdobjetspolymorphiques
#include <iostream>
usingnamespacestd;
/*************
LACLASSEABSTRAITEDEBASE
*****************/
classObject
{
unsignedlongintnew_handle(void);
protected:
unsignedlonginth;
//Identifiantdelobjet.
public:
Object(void);
//Leconstructeur.
virtual~Object(void);
//Ledestructeurvirtuel.
virtualvoidprint(void)=0;//Fonctionvirtuellepure.
unsignedlonginthandle(void)const; //Fonctionrenvoyant
//lenumrodidentification
//delobjet.
};
//CettefonctionnestappelablequeparlaclasseObject:
unsignedlongintObject::new_handle(void)
{
staticunsignedlonginthc=0;
returnhc=hc+1;
//hcestlidentifiantcourant.
//Ilestincrment
}
//chaqueappeldenew_handle.
//LeconstructeurdeObjectdoittreappelparlesclassesdrives:
Object::Object(void)
{
h=new_handle();
//Trouveunnouvelidentifiant.
141
Chapitre8.C++:lacoucheobjet
return;
}
Object::~Object(void)
{
return;
}
unsignedlongintObject::handle(void)const
{
returnh;
//Renvoielenumrodelobjet.
}
/********************LACLASSESAC
classBag:publicObject
******************/
//Laclassesac.Ellehrite
//deObject,carunsacpeut
//encontenirunautre.Lesac
//estimplmentsouslaforme
//dunelistechane.
{
structBagList
{
BagList*next;
Object *ptr;
};
BagList*head;
//Lattedeliste.
public:
Bag(void);
//Leconstructeur:appelceluideObject.
~Bag(void);
//Ledestructeur.
voidprint(void);//Fonctiondaffichagedusac.
boolhas(unsignedlongint)const;
//truesilesaccontientlobjet.
boolis_empty(void)const; //truesilesacestvide.
voidadd(Object&);
//Ajouteunobjet.
voidremove(Object&);
//Retireunobjet.
};
Bag::Bag(void):Object()
{
return; //NefaitriendautrequappelerObject::Object().
}
Bag::~Bag(void)
{
BagList*tmp=head;
while(tmp!=NULL)
{
tmp=tmp>next;
deletehead;
head=tmp;
}
return;
}
142
//Dtruitlalistedobjet.
Chapitre8.C++:lacoucheobjet
voidBag::print(void)
{
BagList*tmp=head;
cout << "Sacn " << handle() << "." << endl;
cout << "
Contenu:" << endl;
while(tmp!=NULL)
{
cout << "\t";
tmp>ptr>print();
tmp=tmp>next;
}
return;
//Indentelasortiedesobjets.
//Affichelalisteobjets.
}
boolBag::has(unsignedlonginth)const
{
BagList*tmp=head;
while(tmp!=NULL&&tmp>ptr>handle()!=h)
tmp=tmp>next;
//Cherchelobjet.
return(tmp!=NULL);
}
boolBag::is_empty(void)const
{
return(head==NULL);
}
voidBag::add(Object&o)
{
BagList*tmp=newBagList;
tmp>ptr=&o;
tmp>next=head;
head=tmp;
return;
}
//Ajouteunobjetlaliste.
voidBag::remove(Object&o)
{
BagList*tmp1=head,*tmp2=NULL;
while(tmp1!=NULL&&tmp1 >ptr>handle()!=o.handle())
{
tmp2=tmp1;
//Cherchelobjet...
tmp1=tmp1 >next;
}
if(tmp1!=NULL)
//etlesupprimedelaliste.
{
if(tmp2!=NULL)tmp2>next=tmp1>next;
elsehead=tmp1 >next;
deletetmp1;
}
return;
}
AveclaclasseBagdfinietellequelle,ilestprsentpossibledestockerdesobjetsdrivantdela
classeObjectaveclesfonctions add et remove :
143
Chapitre8.C++:lacoucheobjet
classMonObjet:publicObject
{
/* Dfinirlamthodeprint()pourlobjet...
};
*/
BagMonSac;
intmain(void)
{
MonObjeta,b,c;
MonSac.add(a);
MonSac.add(b);
MonSac.add(c);
MonSac.print();
MonSac.remove(b);
MonSac.add(MonSac);
MonSac.print();
//Effectuequelquesoprations
//aveclesac:
//Unsacpeutcontenirunsac!
//Attention!Cetappelestrcursif!
//(plantageassur).
return0;
}
Nousavonsvuquelaclassedebaseservaitdemouleauxclassesdrives.Ledroitdempcherune
fonctionmembrevirtuellepuredfiniedansuneclassedrivedaccderencriturenonseulement
auxdonnesdelaclassedebase,maisaussiauxdonnesdelaclassedrive,peutdoncfairepartie
desesprrogatives.Celaestfaisableendclarantlepointeur this commetantunpointeurconstant
surobjetconstant. Nousavonsvuquecelapouvaitsefaireenrajoutantlemotcl const aprsla
dclarationdelafonctionmembre.Parexemple,commelidentifiantdelobjetdebaseestplacen
protected aulieudtreen private,laclasseObjectautorisesesclassesdriveslemodifier.
Cependant,ellepeutempcherlafonction print delemodifierenladclarant const :
classObject
{
unsignedlongintnew_handle(void);
protected:
unsignedlonginth;
public:
Object(void);
//Leconstructeur.
virtualvoidprint(void)const=0; //Fonctionvirtuellepure.
unsignedlonginthandle(void)const;//Fonctionrenvoyant
//lenumrodidentification
//delobjet.
};
144
Chapitre8.C++:lacoucheobjet
Bienentendu,celafonctionnegalementaveclesfonctionsmembresvirtuellesnonpures,etmme
aveclesfonctionsnonvirtuelles.
8.16.Pointeurssurlesmembresduneclasse
Nousavonsdjvulespointeurssurlesobjets.Ilnousrestevoirlespointeurssurlesmembresdes
classes.
Lesclassesregroupentlescaractristiquesdesdonnesetdesfonctionsdesobjets.Lesmembresdes
classesnepeuventdoncpastremanipulssanspasserparlaclasselaquelleilsappartiennent.Par
consquent,ilfaut,lorsquonveutfaireunpointeursurunmembre,indiquerlenomdesaclasse.Pour
cela,lasyntaxesuivanteestutilise:
dfinitionclasse::*pointeur
Parexemple,siuneclassetestcontientdesentiers,letypedepointeursutiliserpourstockerleur
adresseest:
inttest::*
Sionveutdclarerunpointeur p decetype,oncriradonc:
inttest::*p1;
//Construitlepointeursurentier
//delaclassetest.
Unefoislepointeurdclar,onpourralinitialiserenprenantladressedumembredelaclassedutype
correspondant.Pourcela,ilfaudraencorespcifierlenomdelaclasseavecloprateurdersolution
deporte:
p1=&test::i;
//Rcupreladressedei.
Cependant,cespointeursnesontpasutilisablesdirectement.Eneffet,lesdonnesduneclassesont
instanciespourchaqueobjet,etlesfonctionsmembresreoiventsystmatiquementlepointeurthis
surlobjetdemanireimplicite.Onnepeutdoncpasfaireundrfrencementdirectdecespointeurs.
Ilfautspcifierlobjetpourlequellepointeurvatreutilis.Celasefaitaveclasyntaxesuivante:
objet.*pointeur
145
Chapitre8.C++:lacoucheobjet
//Initialiseladonnemembreideaaveclavaleur3.
Pourlesfonctionsmembres,onmettradesparenthsescausedesprioritsdesoprateurs:
inti=(a.*p2)();
//Appellelafonctionlit()pourlobjeta.
//Rcupreladresse
//deladonnemembre
//statique.
Lammesyntaxesappliquerapourlesfonctions:
typedefint(*pg)(void);
pgp4=&test::fonction_statique;
//Rcupreladresse
//dunefonctionmembre
//statique.
146
Chapitre8.C++:lacoucheobjet
staticintj;
public:
test(intj)
{
i=j;
return;
}
staticintget(void)
{
/*returni;
INTERDIT:iestnonstatique
etgetlest!*/
returnj;//Autoris.
}
};
inttest::j=5;
//Initialiselavariablestatique.
typedefint(*pf)(void);
//Pointeurdefonctionrenvoyant
//unentier.
//Initialisationlicite,carget
//eststatique.
pfp=&test::get;
intmain(void)
{
cout << (*p)() << endl;//Affiche5.Onnespcifiepaslobjet.
return0;
}
147
Chapitre8.C++:lacoucheobjet
148
Chapitre9.LesexceptionsenC++
Uneexceptionestlinterruptiondelexcutionduprogrammelasuitedunvnementparticulier.Le
butdesexceptionsestderaliserdestraitementsspcifiquesauxvnementsquiensontlacause.Ces
traitementspeuventrtablirleprogrammedanssonmodedefonctionnementnormal,auquelcasson
excutionreprend.Ilsepeutaussiqueleprogrammesetermine,siaucuntraitementnestappropri.
LeC++supportelesexceptionslogicielles,dontlebutestdegrerleserreursquisurviennentlors
delexcutiondesprogrammes.Lorsquunetelleerreursurvient,leprogrammedoitlanceruneex
ception. Lexcutionnormaleduprogrammesarrtedsquelexceptionestlance, etlecontrle
estpassungestionnairedexception.Lorsquungestionnairedexceptionsexcute,onditquila
attraplexception.
Lesexceptionspermettentunegestionsimplifiedeserreurs,parcequellesenreportentletraitement.
Lecodepeutalorstrecritsanssesoucierdescasparticuliers,cequilesimplifiegrandement.Les
casparticulierssonttraitsdanslesgestionnairesdexception.
Engnral, unefonctionquidtecteuneerreurdexcutionnepeutpasseterminernormalement.
Commesontraitementnapaspusedroulernormalement, ilestprobablequelafonctionquila
appeleconsidreelleaussiquuneerreuraeulieuetterminesonexcution.Lerreurremonteainsila
listedesappelantsdelafonctionquiagnrlerreur.Ceprocessuscontinue,defonctionenfonction,
jusqucequelerreursoitcompltementgreoujusqucequeleprogrammesetermine(cecas
survientlorsquelafonctionprincipalenepeutpasgrerlerreur).
Traditionnellement,cemcanismeestimplmentlaidedecodesderetourdesfonctions.Chaque
fonctiondoitrenvoyerunevaleurspcifiquelissuedesonexcution,permettantdindiquersielle
sestcorrectementdrouleounon. Lavaleurrenvoyeestdoncutiliseparlappelantpourdter
minerlanaturedelerreur,et,sierreurilya,prendrelesmesuresncessaires.Cettemthodeper
metchaquefonctiondelibrerlesressourcesquelleaalloueslorsdelaremontedeserreurs,et
deffectuerainsisapartdutraitementderreur.
Malheureusement,cettetechniquencessitedetesterlescodesderetourdechaquefonctionappele,
etlalogiquederreurdveloppefinitpardevenirtrslourde,puisquecestestssimbriquentlesuns
lasuitedesautreset quelecodedutraitement deserreurssetrouvemlangaveclecodedu
fonctionnementnormaldelalgorithme.Cettecomplicationpeutdeveniringrablelorsqueplusieurs
valeursdecodesderetourpeuventtrerenvoyesafindedistinguerlesdiffrentscasderreurpossible,
caril peut endcoulerungrandnombredetestset beaucoupdecasparticuliersgrerdansles
fonctionsappelantes.
Certainsprogrammesutilisentdoncunesolutionastucieuse,quiconsistedporterletraitementdes
erreurseffectuerendehorsdelalgorithmepardessautsverslafindelafonction.Lecodedenet
toyage,quisetrouvealorsaprslalgorithme,estexcutcompltementsitoutsepassecorrectement.
Enrevanche,silamoindreerreurestdtecteencoursdexcution,unsautestralisverslapartie
ducodedenettoyagecorrespondanteautraitementquiadjteffectu.Ainsi,cecodenestcrit
quuneseulefois,etletraitementdeserreursestsituendehorsdutraitementnormal.
Lasolutionprcdenteesttoutfaitvalable(enfait,cestmmelasolutionlaplussimple),maiselle
souffreduninconvnient.Ellerendleprogrammemoinsstructur,cartouteslesressourcesutilises
parlalgorithmedoivent treaccessiblesdepuislecodedetraitement
deserreurs. Cesressources
doiventdonctreplacesdansuneporterelativementglobale,voiredclaresenttedefonction.De
plus,letraitementdescodesderreursmultiplesposetoujourslesmmesproblmesdecomplication
destests.
Lasolutionquimetenoeuvrelesexceptionsestbeaucoupplussimple,puisquelafonctionquidtecte
uneerreurpeutsecontenterdelanceruneexception. Cetteexceptioninterromptlexcutiondela
fonction, etungestionnairedexceptionappropriestrecherch. Larecherchedugestionnairesuit
149
Chapitre9.LesexceptionsenC++
lemmecheminquecelui utilislorsdelaremontedeserreurs:
savoirlalistedesappelants.
Lapremirefonctionappelantequi contient ungestionnairedexceptionappropriprenddoncle
contrle, et effectueletraitement delerreur. Si letraitement est complet, leprogrammereprend
sonexcutionnormale. Danslecascontraire, legestionnairedexceptionpeutrelancerlexception
(auquelcaslegestionnairedexceptionsuivantestrecherch)outerminerleprogramme.
LemcanismedesexceptionsduC++garantitquetouslesobjetsdeclassedestockageautomatique
sontdtruitslorsquelexceptionquiremontesortdeleurporte.Ainsi,sitouteslesressourcessont
encapsulesdansdesclassesdisposantdundestructeurcapabledelesdtruireoudelesramener
dansuntat cohrent, laremontedesexceptionseffectueautomatiquement lemnage. Deplus,
lesexceptionspeuventtretypes, etcaractriserainsilanaturedelerreurquisestproduite. Ce
mcanismeestdoncstrictementquivalententermesdefonctionnalitsauxcodesderreursutiliss
prcdemment.
Commeonlevoit, lesexceptionspermettent desimplifier lecode, enreportant endehorsde
lalgorithmenormalletraitementdeserreurs.Parailleurs,lalogiquederreurestcompltementprise
enchargeparlelangage,etleprogrammeurnaplusfairelestestsquipermettentdedterminerle
traitementappropripourchaquetypederreur.LesmcanismesdegestiondesexceptionsduC++
sontdcritsdanslesparagraphessuivants.
9.1.Lancementetrcuprationduneexception
EnC++, lorsquilfautlanceruneexception, ondoitcrerunobjetdontlaclassecaractrisecette
exception,etutiliserlemotcl throw.Sasyntaxeestlasuivante:
throwobjet;
o objet estlobjetcorrespondantlexception.Cetobjetpeuttredenimportequeltype,etpourra
ainsicaractriserpleinementlexception.
Lexceptiondoitalorstretraiteparlegestionnairedexceptioncorrespondant.Onnepeutattraper
quelesexceptionsquisontapparuesdansunezonedecodelimite(cettezoneestditeprotgecontre
leserreursdexcution),passurtoutunprogramme.Ondoitdoncplacerlecodesusceptibledelancer
uneexceptiondunblocdinstructionsparticulier.Ceblocestintroduitaveclemotcltry :
try
{
//Codesusceptibledegnrerdesexceptions...
}
Notezquelesobjetsdeclassedestockageautomatiquedfinisdanslebloctry sontautomatiquement
dtruitslorsquuneexceptionfaitsortirlecontrleduprogrammedeleurporte.
Cestgalement
lecasdelobjet construit pourlancerlexception. Lecompilateureffectuedoncunecopiedecet
objetpourletransfreraupremierbloc catch capabledelerecevoir. Celaimpliquequilyaitun
constructeurdecopiepourlesclassesdexceptionsnontriviales.
150
Chapitre9.LesexceptionsenC++
Demme,lesblocs catch peuventrecevoirleursparamtresparvaleurouparrfrence,commele
montrelasyntaxeindiquecidessus.Engnral,ilestprfrabledutiliserunerfrence,afindviter
unenouvellecopiedelobjetdelexceptionpourlebloc catch.Toutefois,onprendragardeaufait
quedanscecas,lesmodificationseffectuessurleparamtreseronteffectuesdanslacopiedetravail
ducompilateuretserontdoncgalementvisiblesdanslesblocs catch desfonctionsappelantesou
deportesuprieure,silexceptionestrelanceaprstraitement.
Ilpeutyavoirplusieursgestionnairesdexceptions.Chacuntraiteralesexceptionsquionttgnres
danslebloc try etdontlobjetestdelaclasseindiqueparsonparamtre.Ilnestpasncessairede
donnerunnomlobjet( temp)danslexpression catch.Cependant,celapermetdelercuprer,ce
quipeuttrencessairesilondoitrcuprerdesinformationssurlanaturedelerreur.
Enfin, ilestpossiblededfinirungestionnairedexceptionuniversel, quircupreratouteslesex
ceptionspossibles, quelsquesoient leurstypes. Cegestionnairedexceptiondoit prendrecomme
paramtretroispointsdesuspensionentreparenthsesdanssaclause catch.Bienentendu,dansce
cas,ilestimpossibledespcifierunevariablequicontientlexception,puisquesontypeestindfini.
Exemple91.Utilisationdesexceptions
#include <iostream>
usingnamespacestd;
classerreur
//Premireexceptionpossible,associe
//lobjeterreur.
{
public:
intcause; //Entierspcifiantlacausedelexception.
//Leconstructeur.Ilappelleleconstructeurdecause.
erreur(intc):cause(c){}
//Leconstructeurdecopie.Ilestutilisparlemcanisme
//desexceptions:
erreur(consterreur&source):cause(source.cause){}
};
classother{};
//Objetcorrespondanttoutes
//lesautresexceptions.
intmain(void)
{
inti;
//Typedelexceptiongnrer.
cout << "Tapez0pourgnreruneexceptionErreur,"
"1pouruneEntire:";
cin >> i;
//Onvagnrerunedestroisexceptions
//possibles.
cout << endl;
try
//Blocolesexceptionssontprisesencharge.
{
switch(i)
//Selonletypedexceptiondsire,
{
case0:
{
erreura(0);
throw(a);
//onlancelobjetcorrespondant
//(ici,declasseerreur).
//Celainterromptlecode.breakest
//doncinutileici.
151
Chapitre9.LesexceptionsenC++
}
case1:
{
inta=1;
throw(a);
//Exceptiondetypeentier.
}
default:
//Silutilisateurnapastap0ou1,
{
otherc;
//oncrelobjetc(typedexception
throw(c);
//other)etonlelance.
}
}
}
//findubloctry.Lesblocscatchsuivent:
catch(erreur&tmp)//Traitementdelexceptionerreur...
{
//(avecrcuprationdelacause).
cout << "Erreurerreur!(cause" << tmp.cause << ")" << endl;
}
catch(inttmp)
//Traitementdelexceptionint...
{
cout << "Erreurint!(cause"
<< tmp << ")" << endl;
}
catch(...)
//Traitementdetouteslesautres
{
//exceptions(...).
//Onnepeutpasrcuprerlobjetici.
cout << "Exceptioninattendue!" << endl;
}
return0;
}
Seloncequentrelutilisateur,uneexceptiondutypeerreur,intouotherestgnre.
9.2.Remontedesexceptions
Lesfonctionsintressesparlesexceptionsdoivent
lescapteraveclemot cl catch commeon
lavucidessus.EllespeuventalorseffectuertouslestraitementsderreursqueleC++neferapas
automatiquement.Cestraitementscomprennentgnralementlertablissementdeltatdesdonnes
manipulesparlafonction(dont,pourlesfonctionsmembresduneclasse,lesdonnesmembresde
lobjetcourant),ainsiquelalibrationdesressourcesnonencapsulesdansdesobjetsdeclassede
stockageautomatique(parexemple,lesfichiersouverts,lesconnexionsrseau,etc.).
Unefoiscetravaileffectu,ellespeuvent,siellesledsirent,relancerlexception,afindepermettre
untraitementcomplmentaireparleurfonctionappelante.Leparcoursdelexceptionsarrteradonc
dsquelerreurauratcompltementtraite.Bienentendu,ilestgalementpossibledelancerune
autreexceptionquecellequelonareue,commecepeuttreparexemplelecassiletraitementde
lerreurprovoqueluimmeuneerreur.
Pourrelancerlexceptionencoursdetraitementdansungestionnairedexception,ilfaututiliserle
motcl throw.Lasyntaxeestlasuivante:
throw;
Lexceptionestalorsrelance,aveccommevaleurlobjetquelecompilateuraconstruiteninterne
pourpropagerlexception.Lesgestionnairesdexceptionpeuventdoncmodifierlesparamtresdes
exceptions,silslesattrapentavecunerfrence.
152
Chapitre9.LesexceptionsenC++
Si, lorsquuneexceptionseproduit dansunbloc try, il est impossibledetrouverlebloc catch
correspondantlaclassedecetteexception, ilseproduituneerreurdexcution. Lafonctionpr
dfinie std::terminate estalorsappele. Ellesecontentedappelerunefonctiondetraitement
delerreur, quiellemmeappellelafonction abort delabibliothqueC. Cettefonctiontermine
encatastrophelexcutionduprogrammefautifengnrantunefaute(lesressourcesallouesparle
programmenesontdoncpaslibres,etdesdonnespeuventtreperdues).Cenestgnralement
paslecomportementdsir,aussiestilpossibledelemodifierenchangeantlafonctionappelepar
std::terminate.
Pourcela, ilfaututiliserlafonction std::set_terminate, quiattendenparamtreunpointeur
surlafonctiondetraitementderreur,quineprendaucunparamtreetrenvoievoid.Lavaleurren
voyepar std::set_terminate estlepointeursurlafonctiondetraitementderreurprcdente.
std::terminate et std::set_terminate sontdclareedanslefichierdentte exception.
Note:Commeleursnomslindiquent, std::terminate et std::set_terminate sontdclares
danslespacedenommagestd::,quiestrservpourtouslesobjetsdelabibliothquestandard
std:: devantcesnoms,
C++.Sivousnevoulezpasavoirutilisersystmatiquementleprfixe
vousdevrezajouterlaligne usingnamespacestd; aprsavoirincluslentteexception .
VousobtiendrezdeplusamplesrenseignementssurlesespacesdenommagedansleChapitre
11.
Exemple92.Installationdungestionnairedexceptionavecset_terminate
#include <iostream>
#include <exception>
usingnamespacestd;
voidmon_gestionnaire(void)
{
cout << "Exceptionnongrereue!" << endl;
cout << "Jetermineleprogrammeproprement..."
<< endl;
exit(1);
}
intlance_exception(void)
{
throw2;
}
intmain(void)
{
set_terminate(&mon_gestionnaire);
try
{
lance_exception();
}
catch(doubled)
{
cout << "Exceptiondetypedoublereue:" <<
d << endl;
}
return0;
153
Chapitre9.LesexceptionsenC++
}
9.3.Listedesexceptionsautorisespourunefonction
Ilestpossibledespcifierlesexceptionsquipeuventtrelancesparunefonction.Pourcela,ilfaut
fairesuivresonenttedumotcl throw avec, entreparenthsesetsparespardesvirgules, les
classesdesexceptionsquelleestautoriselancer.Parexemple,lafonctionsuivante:
intfonction_sensible(void)
throw(int,double,erreur)
{
...
}
naledroitdelancerquedesexceptionsdutypeint,doubleouerreur.Siuneexceptiondunautre
typeestlance,parexempleuneexceptiondutypechar*,ilseproduitencoreunefoisuneerreur
lexcution.
Enfait, lafonction std::unexpected est appele. Cettefonctionsecomportedemanire
similaire std::terminate,puisquelleappellepardfautunefonctiondetraitementdelerreur
qui ellemmeappellelafonction std::terminate (et donc abort enfindecompte). Cela
conduit laterminaisonduprogramme. Onpeut encoreunefoischangercecomportement par
dfautenremplaantlafonctionappelepar std::unexpected paruneautrefonctionlaidede
std::set_unexpected, qui est dclaredanslefichier dentte exception. Cettedernire
attendenparamtreunpointeursurlafonctiondetraitement derreur, qui nedoit prendreaucun
paramtreetquinedoitrienrenvoyer. std::set_unexpected renvoielepointeursurlafonction
detraitementderreurprcdemmentappelepar std::unexpected.
Note: Commeleurs noms lindiquent, std::unexpected et std::set_unexpected sont
dclaresdanslespacedenommage std::,qui estrservpourlesobjetsdelabibliothque
standardC++.Sivousnevoulezpasavoirutilisersystmatiquementleprfixe std:: pources
noms, vousdevrezajouter laligne usingnamespacestd; aprsavoir incluslentte
exception. Vousobtiendrezdeplusamplesrenseignementssur lesespacesdenommage
dansleChapitre11.
Ilestpossiblederelanceruneautreexceptionlintrieurdelafonctiondetraitementderreur.Sicette
exceptionsatisfaitlalistedesexceptionsautorises, leprogrammereprendsoncoursnormalement
danslegestionnairecorrespondant.Cestgnralementcequeloncherchefaire.Legestionnaire
peutgalementlanceruneexceptiondetypestd::bad_exception,dclarecommesuitdanslefichier
dentte exception :
classbad_exception:publicexception
{
public:
bad_exception(void)throw();
bad_exception(constbad_exception&)throw();
bad_exception&operator=(constbad_exception&)throw();
virtual~bad_exception(void)throw();
virtualconstchar*what(void)constthrow();
};
154
Chapitre9.LesexceptionsenC++
Celaapourconsquencedeterminerleprogramme.
Enfin, le gestionnaire dexceptions nonautorises peut directement mettre fin lexcution
duprogrammeenappelant std::terminate. Cest lecomportement utilispar lafonction
std::unexpected dfiniepardfaut.
Exemple93.Gestiondelalistedesexceptionsautorises
#include <iostream>
#include <exception>
usingnamespacestd;
voidmon_gestionnaire(void)
{
cout << "Uneexceptionillgaleatlance."<< endl;
cout << "Jerelanceuneexceptiondetypeint."<< endl;
throw2;
}
intf(void)throw(int)
{
throw"5.35";
}
intmain(void)
{
set_unexpected(&mon_gestionnaire);
try
{
f();
}
catch(inti)
{
cout << "Exceptiondetypeintreue:" <<
i << endl;
}
return0;
}
Note:Lalistedesexceptionsautorisesdansunefonctionnefaitpaspartiedesasignature.
Ellenintervientdoncpasdanslesmcanismesdesurchargedesfonctions.Deplus,elledoitse
placeraprslemotcl const danslesdclarationsdefonctionsmembres const (enrevanche,
elledoitseplaceravant =0 danslesdclarationsdesfonctionsvirtuellespures).
Onprendragardeaufaitquelesexceptionsnesontpasgnresparlemcanismedegestion
deserreursduC++(niduC).Celasignifiequepouravoiruneexception,ilfautlalancer,lecom
pilateurneferapaslestestspourvous(testsdedbordementsnumriquesdanslescalculspar
exemple).Celasupposeraitdeprdfinirunensembledeclassespourleserreursgnriques.
Lestestsdevaliditduneoprationdoivent donctrefaitsmalgrtout et, lecaschant, il
fautlanceruneexceptionpourreporterletraitementencasdchec.Demme,lesexceptions
gnresparlamachinehteduprogrammenesontengnral pasrcupresparlesimpl
mentationset,sielleslesont,lesprogrammesquilesutilisentnesontpasportables.
155
Chapitre9.LesexceptionsenC++
9.4.Hirarchiedesexceptions
LemcanismedesexceptionsduC++sebasesurletypagedesobjets,puisquelelancementdune
exceptionncessitelaconstructiondunobjetquilacaractrise,etlebloc catch destinationdecette
exceptionseraslectionnenfonctiondutypedecetobjet.Bienentendu,lesobjetsutilisspourlancer
lesexceptionspeuventcontenirdesinformationsconcernantlanaturedeserreursquiseproduisent,
maisilestgalementpossibledeclassifierceserreursparcatgoriesensebasantsurleurstypes.
Eneffet,lesobjetsexceptionspeuventtredesinstancesdeclassesdisposantderelationsdhritage.
Commelesobjetsdesclassesdrivespeuventtreconsidrscommedesinstancesdeleursclasses
debase, lesgestionnairesdexceptionpeuvent rcuprerlesexceptionsdecesclassesdrivesen
rcuprant unobjet dutypedunedeleursclassesdebase.
Ainsi, il est possibledeclassifierles
diffrentscasderreursendfinissantunehirarchiedeclassedexceptions,etdcriredestraitements
gnriquesennutilisantquelesobjetsduncertainniveaudanscettehirarchie.
Lemcanismedesexceptionssemontredoncpluspuissantquetouteslesautresmthodesdetraite
mentderreursceniveau,puisquelaslectiondugestionnairederreurestautomatiquementralise
parlelangage.Celapeuttretrspratiquepourpeuquelonaitdfinicorrectementsahirarchiede
classesdexceptions.
Exemple94.Classificationdesexceptions
#include <iostream>
usingnamespacestd;
//Classedebasedetouteslesexceptions:
classExRuntimeError
{
};
//Classedebasedesexceptionspouvantseproduire
//lorsdemanipulationsdefichiers:
classExFileError:publicExRuntimeError
{
};
//Classesdeserreursdemanipulationdesfichiers:
classExInvalidName:publicExFileError
{
};
classExEndOfFile:publicExFileError
{
};
classExNoSpace:publicExFileError
{
};
classExMediumFull:publicExNoSpace
{
};
classExFileSizeMaxLimit:publicExNoSpace
{
156
Chapitre9.LesexceptionsenC++
};
//Fonctionfaisantuntravailquelconquesurunfichier:
voidWriteData(constchar*szFileName)
{
//Exemplederreur:
if(szFileName==NULL)throwExInvalidName();
else
{
//Traitementdelafonction
//etc.
//Lancementduneexception:
throwExMediumFull();
}
}
voidSave(constchar*szFileName)
{
try
{
WriteData(szFileName);
}
//Traitementdunerreurspcifique:
catch(ExInvalidName&)
{
cout << "Impossibledefairelasauvegarde" << endl;
}
//Traitementdetouteslesautreserreursengroupe:
catch(ExFileError&)
{
cout << "Erreurdentre/sortie"<< endl;
}
}
intmain(void)
{
Save(NULL);
Save("data.dat");
return0;
}
LabibliothquestandardC++dfinitellemmeuncertainnombredexceptionsstandards,quisont
utilisespoursignalerleserreursquiseproduisentlexcutiondesprogrammes.Quelquesunesde
cesexceptionsontdjtprsentesaveclesfonctionnalitsquisontsusceptiblesdeleslancer.Vous
trouverezunelistecompltedesexceptionsdelabibliothquestandardduC++danslaSection13.2.
9.5.Exceptionsdanslesconstructeurs
Ilestparfaitementlgaldelanceruneexceptiondansunconstructeur.Enfait,cestmmelaseule
solutionpoursignaleruneerreurlorsdelaconstructiondunobjet,puisquelesconstructeursnont
pasdevaleurderetour.
Lorsquuneexceptionest lancepartirdunconstructeur, laconstructiondelobjet choue. Par
consquent,lecompilateurnappellerajamaisledestructeurpourcetobjet,puisquecelanapasde
157
Chapitre9.LesexceptionsenC++
sens.Cependant,cecomportementsoulveleproblmedesobjetspartiellementinitialiss,pourles
quelsilestncessairedefaireunpeudenettoyagelasuitedulancementdelexception.LeC++
disposedoncdunesyntaxeparticulirepourlesconstructeursdesobjetssusceptiblesdelancerdes
exceptions. Cettesyntaxepermetsimplementdutiliserunbloc try pourlecorpsdefonctiondes
constructeurs.Lesblocs catch suiventalorsladfinitionduconstructeur,eteffectuentlalibration
desressourcesqueleconstructeurauraitpualloueravantquelexceptionneseproduise.
Lecomportementdubloc catch desconstructeursavecbloc try estdiffrentdeceluidesblocs
catch classiques.Eneffet,lesexceptionsnesontnormalementpasrelancesunefoisquellesont
ttraites.Commeonlavucidessus,ilfaututiliserexplicitementlemotcl throw pourrelancer
uneexceptionlissuedesontraitement.Danslecasdesconstructeursavecunbloc try cependant,
lexceptionestsystmatiquementrelance.Lebloc catch duconstructeurnedoitdoncprendreen
chargequeladestructiondesdonnesmembrespartiellementconstruites, etilfauttoujourscapter
lexceptionauniveauduprogrammequiacherchcrerlobjet.
Note: Cettedernirergleimpliquequelesprogrammesdclarant desobjetsglobauxdont
leconstructeurpeut lanceruneexceptionrisquent deseterminerencatastrophe. Eneffet, si
uneexceptionestlanceparceconstructeurlinitialisationduprogramme,aucungestionnaire
dexceptionneseraenmesuredelacapterlorsquelebloccatch larelancera.
Exemple95.Exceptionsdanslesconstructeurs
#include <iostream>
#include <stdlib.h>
usingnamespacestd;
classA
{
char*pBuffer;
int *pData;
public:
A()throw(int);
~A()
{
cout << "A::~A()" << endl;
}
staticvoid*operatornew(size_ttaille)
158
Chapitre9.LesexceptionsenC++
{
cout << "new()" << endl;
returnmalloc(taille);
}
staticvoidoperatordelete(void*p)
{
cout << "delete" << endl;
free(p);
}
};
//Constructeursusceptibledelanceruneexception:
A::A()throw(int)
try
{
pBuffer=NULL;
pData=NULL;
cout << "Dbutduconstructeur" << endl;
pBuffer=newchar[256];
cout << "Lancementdelexception"<< endl;
throw2;
//Codeinaccessible:
pData=newint;
}
catch(int)
{
cout << "Jefaislemnage..."
<< endl;
delete[]pBuffer;
deletepData;
}
intmain(void)
{
try
{
A*a=newA;
}
catch(...)
{
cout << "Ae,mmepasmal!"
}
return0;
}
<< endl;
Danscetexemple,lorsdelacrationdynamiquedunobjetA,uneerreurdinitialisationseproduit
et uneexceptionest lance. Celleci est alorstraitedanslebloc catch qui suit ladfinitiondu
constructeurdelaclasseA.Loprateur delete estbienappelautomatiquement,maisledestructeur
deAnestjamaisexcut.
Engnral, siuneclassehritedeuneouplusieursclassesdebase, lappelauxconstructeursdes
classesdebasedoitsefaireentrelemotcl try etlapremireaccolade.Eneffet,lesconstructeurs
desclassesdebasesont susceptibles, euxaussi, delancerdesexceptions. Lasyntaxeest alorsla
suivante:
Classe::Classe
159
Chapitre9.LesexceptionsenC++
try:Base(paramtres)[,Base(paramtres)[...]]
{
}
catch...
160
Chapitre10.Identificationdynamiquedes
types
LeC++estunlangagefortementtyp.Malgrcela,ilsepeutqueletypeexactdunobjetsoitinconnu
causedelhritage.Parexemple,siunobjetestconsidrcommeunobjetduneclassedebasede
savritableclasse,onnepeutpasdtermineraprioriquelleestsavritablenature.
Cependant,lesobjetspolymorphiques(qui,rappelonsle,sontdesobjetsdisposantdemthodesvir
tuelles)conserventdesinformationssurleurtypedynamique,savoirleurvritablenature.Eneffet,
lorsdelappeldesmthodesvirtuelles,lamthodeappeleestlamthodedelavritableclassede
lobjet.
Ilestpossibledutilisercettepropritpourmettreenplaceunmcanismepermettantdidentifierle
typedynamiquedesobjets,maiscettemaniredeprocdernestpasportable.LeC++fournitdonc
unmcanismestandardpermettantdemanipulerlesinformationsdetypedesobjetspolymorphiques.
Cemcanismeprendenchargelidentificationdynamiquedestypesetlavrificationdelavalidit
destranstypagesdanslecadredeladrivation.
10.1.Identificationdynamiquedestypes
10.1.1.Loprateurtypeid
LeC++fournitloprateur typeid,quipermetdercuprerlesinformationsdetypedesexpressions.
Sasyntaxeestlasuivante:
typeid(expression)
o expression estlexpressiondontilfautdterminerletype.
Lersultatdeloprateur typeid estunerfrencesurunobjetconstantdeclassetype_info.Cette
classeseradcritedanslaSection10.1.2.
Lesinformationsdetypercupressontlesinformationsdetypestatiquepourlestypesnonpoly
morphiques.Celasignifiequelobjetrenvoypartypeid caractriseraletypedelexpressionfournie
enparamtre,quecetteexpressionsoitunsousobjetdunobjetplusdrivounon.Enrevanche,pour
lestypespolymorphiques,siletypenepeutpastredterminstatiquement(cestdirelacom
pilation),unedterminationdynamique(cestdirelexcution)dutypealieu,etlobjetdeclasse
type_inforenvoydcritlevraitypedelexpression(mmesiellereprsenteunsousobjetdunobjet
duneclassedrive).Cettesituationpeutarriverlorsquonmanipuleunobjetlaidedunpointeur
oudunerfrencesuruneclassedebasedelaclassedecetobjet.
Exemple101.Oprateurtypeid
#include <typeinfo>
usingnamespacestd;
classBase
{
public:
virtual~Base(void);
//Ilfautunefonctionvirtuelle
//pouravoirdupolymorphisme.
161
Chapitre10.Identificationdynamiquedestypes
};
Base::~Base(void)
{
return;
}
classDerivee:publicBase
{
public:
virtual~Derivee(void);
};
Derivee::~Derivee(void)
{
return;
}
intmain(void)
{
Derivee*pd=newDerivee;
Base*pb=pd;
consttype_info&t1=typeid(*pd); //t1qualifieletypede*pd.
consttype_info&t2=typeid(*pb); //t2qualifieletypede*pb.
return0;
}
Lesobjets t1 et t2 sontgaux,puisquilsqualifienttouslesdeuxlemmetype(savoir,laclasse
Derivee). t2 necontientpaslesinformationsdetypedelaclasseBase, parcequelevraitypede
lobjetpointpar pb estlaclasseDerivee.
Note:Notezquelaclassetype_infoestdfiniedanslespacedenommage std::,rservla
bibliothquestandardC++,danslenttetypeinfo .Parconsquent,sonnomdoittreprcd
duprfixe std::.Vouspouvezvouspasserdeceprfixeenimportantlesdfinitionsdelespace
denommagedelabibliothquestandardlaidedunedirective using.Voustrouverezdeplus
amplesrenseignementssurlesespacesdenommagedansleChapitre11.
Onferabienattentiondrfrencerlespointeurs,carsinon,onobtientlesinformationsdetypesur
cepointeur,passurlobjetpoint.Silepointeurdrfrencestlepointeurnul,loprateur typeid
lanceuneexceptiondont lobjet est uneinstancedelaclassebad_typeid. Cetteclasseest dfinie
commesuitdanslentte typeinfo :
classbad_typeid:publiclogic
{
public:
bad_typeid(constchar*what_arg):logic(what_arg)
{
return;
}
voidraise(void)
{
handle_raise();
throw*this;
}
162
Chapitre10.Identificationdynamiquedestypes
};
10.1.2.Laclassetype_info
Lesinformationsdetypesontenregistresdansdesobjetsdelaclassetype_infoprdfinieparle
langage.Cetteclasseestdclaredanslentte typeinfo delamaniresuivante:
classtype_info
{
public:
virtual~type_info();
booloperator==(consttype_info&rhs)const;
booloperator!=(consttype_info&rhs)const;
boolbefore(consttype_info&rhs)const;
constchar*name()const;
private:
type_info(consttype_info&rhs);
type_info&operator=(consttype_info&rhs);
};
Lesobjetsdelaclassetype_infonepeuventpastrecopis,puisqueloprateurdaffectationetle
constructeurdecopiesonttouslesdeuxdclarsprivate.Parconsquent,leseulmoyendegnrer
unobjetdelaclassetype_infoestdutiliserloprateur typeid.
Lesoprateursdecomparaisonpermettentdetesterlgalitetladiffrencededeuxobjetstype_info,
cequirevientexactementcomparerlestypesdesexpressions.
Lesobjetstype_infocontiennentdesinformationssurlestypessouslaformedechanesdecaractres.
Unedeceschanesreprsenteletypesousuneformelisibleparuntrehumain,etuneautresousune
formeplusappropriepourletraitementdestypes.Leformatdeceschanesdecaractresnestpas
prcisetpeutvarierduneimplmentationuneautre.Ilestpossibledercuprerlenomlisibledu
typelaidedelamthode name.Lavaleurrenvoyeestunpointeursurunechanedecaractres.On
nedoitpaslibrerlammoireutilisepourstockercettechanedecaractres.
Lamthode before permetdedterminerunordredanslesdiffrentstypesappartenantlamme
hirarchiedeclasses, ensebasant surlespropritsdhritage. Lutilisationdecettemthodeest
toutefoisdifficile, puisquelordreentrelesdiffrentesclassesnest
pasfixet peut dpendrede
limplmentation.
10.2.TranstypagesC++
Lesrglesdedrivationpermettentdassurerlefaitquelorsquonutiliseunpointeursuruneclasse,
lobjetpointexistebienetestbiendelaclassesurlaquellelepointeurestbas.Enparticulier,ilest
possibledeconvertirunpointeursurunobjetenunpointeursurunsousobjet.
Enrevanche,ilestinterditdutiliserunpointeursuruneclassedebasepourinitialiserunpointeursur
uneclassedrive.Pourtant,cetteoprationpeuttrelgale,sileprogrammeursaitquelepointeur
pointebiensurunobjetdelaclassedrive. Lelangageexigecependantuntranstypageexplicite.
Unetellesituationdemandelanalyseduprogrammeafindesavoirsielleestlgaleounon.
163
Chapitre10.Identificationdynamiquedestypes
Parfois,ilestimpossibledefairecetteanalyse.Celasignifiequeleprogrammeurnepeutpascertifier
quelepointeurdontildisposeestunpointeursurunsousobjet.Lemcanismedidentificationdyna
miquedestypespeuttrealorsutilispourvrifier,lexcution,siletranstypageestlgal.Silne
lestpas,untraitementparticulierdoittreeffectu,maissillest,leprogrammepeutsepoursuivre
normalement.
LeC++fournit unjeudoprateursdetranstypagequi permettent defairecesvrificationsdyna
miques,etquidoncsontnettementplussrsqueletranstypagetoutpuissantduCquelonautilis
jusquici.Cesoprateurssontcapablesdefaireuntranstypagedynamique,untranstypagestatique,
untranstypagedeconstanceetuntranstypagederinterprtationdesdonnes.Nousallonsvoirles
diffrentsoprateurspermettantdefairecestranstypages,ainsiqueleursignification.
10.2.1.Transtypagedynamique
Letranstypagedynamiquepermetdeconvertiruneexpressionenunpointeurouunerfrencedune
dynamic_cast.Cetoprateur
classe,ouunpointeursurvoid.Ilestralislaidedeloprateur
imposedesrestrictionslorsdestranstypagesafindegarantiruneplusgrandefiabilit:
ileffectueunevrificationdelavaliditdutranstypage;
ilnestpaspossibledliminerlesqualificationsdeconstance(pourcela,ilfaututiliserloprateur
const_cast,quelonverraplusloin).
Enrevanche,loprateurdynamic_cast permetparfaitementdaccrotrelaconstanceduntypecom
plexe,commelefontlesconversionsimplicitesdulangagevuesdanslaSection3.2etdanslaSection
4.7.
Ilnepeutpastravaillersurlestypesdebasedulangage,saufvoid*.
Lasyntaxedeloprateur dynamic_cast estdonnecidessous:
dynamic_cast<type>(expression)
o type dsigneletypecibledutranstypage,et
expression lexpressiontranstyper.
Letranstypagedunpointeuroudunerfrenceduneclassedriveenclassedebasesefaitdonc
directement, sansvrificationdynamique, puisquecetteoprationest toujoursvalide. Leslignes
suivantes:
//LaclasseBhritedelaclasseA:
B*pb;
A*pA=dynamic_cast <A* >(pB);
sontdoncstrictementquivalentescellesci:
//LaclasseBhritedelaclasseA:
B*pb;
A*pA=pB;
Toutautretranstypagedoitsefairepartirduntypepolymorphique,afinquelecompilateurpuisse
utiliserlidentificationdynamiquedestypeslorsdutranstypage.Letranstypagedunpointeurdun
objetversunpointeurdetypevoidrenvoieladressedudbutdelobjetleplusdriv,cestdire
164
Chapitre10.Identificationdynamiquedestypes
ladressedelobjetcomplet.Letranstypagedunpointeuroudunerfrencesurunsousobjetdun
objet versunpointeurouunerfrencedelobjet complet est effectuaprsvrificationdutype
dynamique. Silobjetpointourfrencestbiendutypeindiqupourletranstypage, lopration
sedroulecorrectement.Enrevanche,silnestpasdubontype, dynamic_cast neffectuepasle
transtypage.Siletypecibleestunpointeur,lepointeurnulestrenvoy.Sienrevanchelexpression
caractriseunobjetouunerfrencedobjet,uneexceptiondetypebad_castestlance.
Laclassebad_castestdfiniecommesuitdanslentte typeinfo :
classbad_cast:publicexception
{
public:
bad_cast(void)throw();
bad_cast(constbad_cast&)throw();
bad_cast&operator=(constbad_cast&)throw();
virtual~bad_cast(void)throw();
virtualconstchar*what(void)constthrow();
};
Lorsduntranstypage,aucuneambigutnedoitavoirlieupendantlarecherchedynamiquedutype.
Detellesambigutspeuventapparatredanslescasdhritagemultiple,oplusieursobjetsdemme
typepeuventcoexisterdanslemmeobjet.Cetterestrictionmisepart,loprateur dynamic_cast
estcapabledeparcourirunehirarchiedeclasseaussibienverticalement(convertirunpointeurde
sousobjetversunpointeurdobjetcomplet)quetransversalement(convertirunpointeurdobjetvers
unpointeurdunautreobjetfrredanslahirarchiedeclasses).
Loprateur dynamic_cast peuttreutilisdanslebutdeconvertirunpointeursuruneclassede
basevirtuelleversunedessesclassesfilles,cequenepouvaientpasfairelestranstypagesclassiques
duC. Enrevanche, ilnepeutpastreutilisafindaccderdesclassesdebasequinesontpas
visibles(enparticulier,lesclassesdebasehritesen private).
Exemple102.Oprateurdynamic_cast
structA
{
virtualvoidf(void)
{
return;
}
};
structB:virtualpublicA
{
};
structC:virtualpublicA,publicB
{
};
structD
{
virtualvoidg(void)
{
return;
}
165
Chapitre10.Identificationdynamiquedestypes
};
structE:publicB,publicC,publicD
{
};
intmain(void)
{
Ee;
//econtientdeuxsousobjetsdeclasseB
//(maisunseulsousobjetdeclasseA).
//LessousobjetsdeclasseCetDsont
//frres.
A*pA=&e;
//Drivationlgale:lesousobjet
//declasseAestunique.
//C*pC=(C*)pA;//Illgal:Aestuneclassedebase
//virtuelle(erreurdecompilation).
C*pC=dynamic_cast <C* >(pA); //Lgal.Transtypage
//dynamiquevertical.
D*pD=dynamic_cast <D* >(pC); //Lgal.Transtypage
//dynamiquehorizontal.
B*pB=dynamic_cast <B* >(pA); //Lgal,maischouera
//lexcution(ambigut).
return0;
10.2.2.Transtypagestatique
Contrairementautranstypagedynamique,letranstypagestatiqueneffectueaucunevrificationdes
typesdynamiqueslorsdutranstypage.Ilestdoncnettementplusdangereuxqueletranstypagedyna
mique.Cependant,contrairementautranstypageCclassique,ilnepermettoujourspasdesupprimer
lesqualificationsdeconstance.
Letranstypagestatiqueseffectuelaidedeloprateur static_cast,dontlasyntaxeestexacte
mentlammequecelledeloprateur dynamic_cast :
static_cast<type>(expression)
dynamic_cast.
Cetteexpressionconstruitunobjettemporairequelconquedetypetypeetlinitialiseaveclavaleur
deexpression.Contrairementloprateur dynamic_cast,loprateur static_cast permetdonc
deffectuerlesconversionsentrelestypesautresquelesclassesdfiniesparlutilisateur.
Aucune
vrificationdelavaliditdelaconversionnalieucependant(commepourletranstypageCclassique).
Si unetelleexpressionnest pasvalide, letranstypagepeut malgrtout avoirlieusil sagit dun
transtypageentreclassesdrivesetclassesdebase.Loprateur static_cast permetdeffectuer
lestranstypagesdecetypedanslesdeuxsens(classedebaseversclassedriveetclassedrive
versclassedebase). Letranstypageduneclassedebaseversuneclassedrivenedoit
trefait
166
Chapitre10.Identificationdynamiquedestypes
quelorsquonestsrquilnyapasdedanger,puisquaucunevrificationdynamiquenalieuavec
static_cast.
Enfin,touteslesexpressionspeuventtreconvertiesenvoidavecdesqualificationsdeconstanceet
devolatilit.Cetteoprationasimplementpourbutdesupprimerlavaleurdelexpression(puisque
voidreprsenteletypevide).
10.2.3.Transtypagedeconstanceetdevolatilit
Lasuppressiondesattributsdeconstanceet
devolatilitpeut treralisegrceloprateur
const_cast.Cetoprateursuitexactementlammesyntaxequelesoprateurs dynamic_cast et
static_cast :
const_cast<type>(expression)
10.2.4.Rinterprtationdesdonnes
Loprateurdetranstypageleplusdangereuxest reinterpret_cast.Sasyntaxeestlammeque
celledesautresoprateursdetranstypage dynamic_cast, static_cast et const_cast :
reinterpret_cast<type>(expression)
Cetoprateurpermetderinterprterlesdonnesduntypeenunautretype.Aucunevrificationde
lavaliditdecetteoprationnestfaite.Ainsi,leslignessuivantes:
doublef=2.3;
inti=1;
const_cast<int& >(f)=i;
sontstrictementquivalentesauxlignessuivantes:
doublef=2.3;
inti=1;
*((int*)&f)=i;
ilnedoitpaspermettrelasuppressiondesattributsdeconstanceetdevolatilit;
167
Chapitre10.Identificationdynamiquedestypes
168
ildoittresymtrique(cestdirequelarinterprtationduntypeT1entantquetypeT2,puisla
rinterprtationdursultatentypeT1doitredonnerlobjetinitial).
Chapitre11.Lesespacesdenommage
Lesespacesdenommagesontdeszonesdedclarationquipermettentdedlimiterlarecherchedes
nomsdesidentificateursparlecompilateur. Leurbutestessentiellementderegrouperlesidentifi
cateurslogiquementetdviterlesconflitsdenomsentreplusieurspartiesdunmmeprojet.
Par
exemple,sideuxprogrammeursdfinissentdiffremmentunemmestructuredansdeuxfichiersdif
frents,unconflitentrecesdeuxstructuresauralieuaumieuxlditiondeliens,etaupirelorsde
lutilisationcommunedessourcesdecesdeuxprogrammeurs.Cetypedeconflitprovientdufaitque
leC++nefournitquunseulespacedenommagedeporteglobale,
danslequelilnedoityavoir
aucunconflitdenom.Grceauxespacesdenommagenonglobaux,cetypedeproblmepeuttre
plusfacilementvit,parcequelonpeutviterdedfinirlesobjetsglobauxdanslaporteglobale.
11.1.Dfinitiondesespacesdenommage
11.1.1.Espacesdenommagenommes
Lorsqueleprogrammeurdonneunnomunespacedenommage,celuiciestappelunespacede
nommagenomm.Lasyntaxedecetypedespacedenommageestlasuivante:
namespacenom
{
dclarations|dfinitions
}
nom estlenomdelespacedenommage,et dclarations et dfinitions sontlesdclarationset
lesdfinitionsdesidentificateursquiluiappartiennent.
Contrairementauxrgionsdclarativesclassiquesdulangage(commeparexemplelesclasses),un
namespace peuttredcoupenplusieursmorceaux.Lepremiermorceauxsertdedclaration,etles
suivantsdextensions.Lasyntaxepouruneextensiondespacedenommageestexactementlamme
quecelledelapartiededclaration.
Exemple111.Extensiondenamespace
namespaceA
{
inti;
}
//DclarationdelespacedenommageA.
namespaceB
{
inti;
}
//DclarationdelespacedenommageB.
namespaceA
{
intj;
}
//ExtensiondelespacedenommageA.
Lesidentificateursdclarsoudfinislintrieurdunmmeespacedenommagenedoiventpas
entrerenconflit.Ilspeuventavoirlesmmesnoms,maisseulementdanslecadredelasurcharge.Un
169
Chapitre11.Lesespacesdenommage
espacedenommagesecomportedoncexactementcommeleszonesdedclarationdesclassesetde
laporteglobale.
Laccsauxidentificateursdesespacesdenommagesefaitpardfautgrceloprateurdersolution
deporte( ::),etenqualifiantlenomdelidentificateurutiliserdunomdesonespacedenommage.
Cependant,cettequalificationestinutilelintrieurdelespacedenommageluimme,exactement
commepourlesmembresdesclasseslintrieurdeleurclasse.
Exemple112.Accsauxmembresdunnamespace
inti=1;
//iestglobal.
namespaceA
{
inti=2;//idelespacedenommageA.
intj=i;//UtiliseA::i.
}
intmain(void)
{
i=1;
//Utilise::i.
A::i=3; //UtiliseA::i.
return0;
}
Lesfonctionsmembresdunespacedenommagepeuventtredfinieslintrieurdecetespace,
exactementcommelesfonctionsmembresdeclasses.Ellespeuventgalementtredfiniesendehors
decetespace,silonutiliseloprateurdersolutiondeporte.Lesfonctionsainsidfiniesdoivent
apparatreaprsleurdclarationdanslespacedenommage.
Exemple113.Dfinitionexternedunefonctiondenamespace
namespaceA
{
intf(void);
}
intA::f(void)
{
return0;
}
//DclarationdeA::f.
//DfinitiondeA::f.
Ilestpossiblededfinirunespacedenommagelintrieurdunautreespacedenommage.Cepen
dant,cettedclarationdoitobligatoirementavoirlieuauniveaudclaratifleplusexternedelespace
denommagequicontientlesousespacedenommage. Onnepeutdoncpasdclarerdespacesde
nommagelintrieurdunefonctionoulintrieurduneclasse.
Exemple114.Dfinitiondenamespacedansunnamespace
namespaceConteneur
{
inti;
namespaceContenu
{
intj;
}
170
//Conteneur::i.
//Conteneur::Contenu::j.
Chapitre11.Lesespacesdenommage
}
11.1.2.Espacesdenommageanonymes
Lorsque,lorsdeladclarationdunespacedenommage,aucunnomnestdonn,unespacedenom
mageanonymeestcr.Cetypedespacedenommagepermetdassurerlunicitdunomdelespace
denommageainsidclar.Lesespacesdenommageanonymespeuventdoncremplacerefficacement
lemotcl static pourrendreuniquedesidentificateursdansunfichier.Cependant,ellessontplus
puissantes,parcequelonpeutgalementdclarerdesespacesdenommageanonymeslintrieur
dautresespacesdenommage.
Exemple115.Dfinitiondenamespaceanonyme
namespace
{
inti;
}
//quivalentunique::i;
//Dclareunique::i.
//Utiliseunique::i.
//DfinitA::unique::i.
//DfinitA::unique::j.
//Erreur:ambigutentreunique::i
//etA::unique::i.
171
Chapitre11.Lesespacesdenommage
++A::i;
++j;
//Erreur:A::inestpasdfini
//(seulA::unique::ilest).
//Correct:++A::unique::j.
}
}
11.1.3.Aliasdespacesdenommage
Lorsquunespacedenommageporteunnomtrscompliqu,
aliaspourcenom.Laliasauraalorsunnomplussimple.
ilpeuttreavantageuxdedfinirun
Cetteoprationpeuttreraliselaidedelasyntaxesuivante:
namespacenom_alias=nom;
nom_alias est ici lenomdelaliasdelespacedenommage,
nommageluimme.
Lesnomsdonnsauxaliasdespacesdenommagenedoiventpasentrerenconflitaveclesnomsdes
autresidentificateursdummeespacedenommage,queceluicisoitlespacedenommagedeporte
globaleounon.
11.2.Dclarationusing
Lesdclarationsusingpermettentdutiliserunidentificateurdunespacedenommagedemanire
simplifie,sansavoirspcifiersonnomcomplet(cestdirelenomdelespacedenommagesuivi
dunomdelidentificateur).
11.2.1.Syntaxedesdclarationsusing
Lasyntaxedesdclarationsusingestlasuivante:
usingidentificateur;
o identificateur estlenomcompletdelidentificateurutiliser,avecqualificationdespacede
nommage.
Exemple117.Dclarationusing
namespaceA
{
inti;
intj;
}
voidf(void)
{
usingA::i;
i=1;
j=1;
return;
172
//DclareA::i.
//DclareA::j.
//A::ipeuttreutilissouslenomi.
//quivalentA::i=1.
//Erreur!jnestpasdfini!
Chapitre11.Lesespacesdenommage
}
//DclarationdelaliasB::i,quireprsenteA::i.
//Lgal:doubledclarationdeA::i.
//DclarevoidB::f(void),
//fonctionidentiqueA::f.
}
intmain(void)
{
B::f();
return0;
}
//AppelleA::f.
//festsynonymedeA::f(int).
//festtoujourssynonymedeA::f(int),
//maispasdeA::f(char).
}
voidg()
{
f(a);
//AppelleA::f(int),mmesiA::f(char)
173
Chapitre11.Lesespacesdenommage
//existe.
}
11.2.2.Utilisationdesdclarationsusingdanslesclasses
Unedclaration using peut treutilisedansladfinitionduneclasse. Danscecas, elledoit se
rapporteruneclassedebasedelaclassedanslaquelleelleestutilise.Deplus,lidentificateurdonn
ladclaration using doittreaccessibledanslaclassedebase(cestdiredetype protected ou
public).
Exemple1111.Dclarationusingdansuneclasse
namespaceA
{
floatf;
}
classBase
{
inti;
public:
intj;
};
classDerivee:publicBase
{
usingA::f;
//Illgal:fnestpasdansuneclasse
174
Chapitre11.Lesespacesdenommage
usingBase::i;
public:
usingBase::j;
};
//debase.
//Interdit:Deriveenapasledroit
//dutiliserBase::i.
//Lgal.
Quandunefonctionduneclassedebaseestintroduitedansuneclassedrivelaidedunedclara
tion using,etquunefonctiondemmenometdemmesignatureestdfiniedanslaclassedrive,
cettedernirefonctionsurchargelafonctiondelaclassedebase.Ilnyapasdambigutdanscecas.
175
Chapitre11.Lesespacesdenommage
11.3.Directiveusing
Ladirectiveusingpermetdutiliser,sansspcificationdespacedenommage,nonpasunidentificateur
commedanslecasdeladclaration using,maistouslesidentificateursdecetespacedenommage.
Lasyntaxedeladirectiveusingestlasuivante:
usingnamespacenom;
o nom estlenomdelespacedenommagedontlesidentificateursdoiventtreutilisssansqualifi
cationcomplte.
Exemple1113.Directiveusing
namespaceA
{
inti;
intj;
}
//DclareA::i.
//DclareA::j.
voidf(void)
{
usingnamespaceA;//OnutiliselesidentificateursdeA.
i=1;
//quivalentA::i=1.
j=1;
//quivalentA::j=1.
return;
}
Aprsunedirective using,ilesttoujourspossibledutiliserlesnomscompletsdesidentificateursde
lespacedenommage,maiscenestplusncessaire.Lesdirectives using sontvalidespartirdela
ligneoellessontdclaresjusqulafindublocdeportecourante.Siunespacedenommageest
tenduaprsunedirective using,lesidentificateursdfinisdanslextensiondelespacedenommage
peuventtreutilissexactementcommelesidentificateursdfinisavantladirective using (cest
diresansqualificationcompltedeleursnoms).
Exemple1114.Extensiondenamespaceaprsunedirectiveusing
namespaceA
{
inti;
}
usingnamespaceA;
namespaceA
{
intj;
}
voidf(void)
{
i=0;
//InitialiseA::i.
j=0;
//InitialiseA::j.
return;
}
176
Chapitre11.Lesespacesdenommage
Ilsepeutquelorsdelintroductiondesidentificateursdunespacedenommageparunedirective
using,desconflitsdenomsapparaissent.Danscecas,aucuneerreurnestsignalelorsdeladirective
using. Enrevanche, uneerreurseproduitsiundesidentificateurspourlesquelsilyaconflitest
utilis.
Exemple1115.Conflitentredirectiveusingetidentificateurslocaux
namespaceA
{
inti;
}
//DfinitA::i.
namespaceB
{
inti; //DfinitB::i.
usingnamespaceA;
//A::ietB::isontenconflit.
//Cependant,aucuneerreurnapparat.
}
voidf(void)
{
usingnamespaceB;
i=2;
//Erreur:ilyaambigut.
return;
}
177
Chapitre11.Lesespacesdenommage
178
Chapitre12.Lestemplate
12.1.Gnralits
Nousavonsvuprcdemmentcommentraliserdesstructuresdedonnesrelativementindpendantes
delaclassedeleursdonnes(cestdiredeleurtype)aveclesclassesabstraites.Parailleurs,ilest
faisabledefairedesfonctionstravaillantsurdenombreuxtypesgrcelasurcharge.Jerappellequen
C++,touslestypessontenfaitdesclasses.
Cependant, lemploi desclassesabstraitesest assezfastidieuxet alinconvnient daffaiblir le
contrledestypesralisparlecompilateur.Deplus,lasurchargenestpasgnralisablepourtous
lestypesdedonnes.Ilseraitpossibledutiliserdesmacrospourfairedesfonctionsatypiquesmais
celaseraitaudtrimentdelatailleducode.
LeC++permet dersoudrecesproblmesgrceauxparamtresgnriques, quelonappelleen
coreparamtrestemplate. Unparamtre template estsoituntypegnrique, soituneconstante
template
dontletypeestassimilableuntypeintgral.Commeleurnomlindique,lesparamtres
permettentdeparamtrerladfinitiondesfonctionsetdesclasses.Lesfonctionsetlesclassesainsi
paramtressontappelesrespectivementfonctionstemplateetclassestemplate.
Lesfonctionstemplatesontdoncdesfonctionsquipeuventtravaillersurdesobjetsdontletypeestun
typegnrique(cestdireuntypequelconque),ouquipeuventtresparamtrsparuneconstante
detypeintgral.Lesclassestemplatesontdesclassesquicontiennentdesmembresdontletypeest
gnriqueouquidpendentdunparamtreintgral.
Engnral, lagnrationducodealieulorsduneoprationaucoursdelaquellelestypesgn
riquessontremplacspardesvraistypesetlesparamtresdetypeintgralprennentleurvaleur.Cette
oprationsappellelinstanciationdestemplate.Ellealieulorsquonutiliselafonctionoulaclasse
template pourlapremirefois.Lestypesrelsutiliserlaplacedestypesgnriquessontd
terminslorsdecettepremireutilisationparlecompilateur,soitimplicitementpartirducontexte
dutilisationdu template,soitparlesparamtresdonnsexplicitementparleprogrammeur.
12.2.Dclarationdesparamtrestemplate
Lesparamtres template sont,commeonlavu,soitdestypesgnriques,soitdesconstantesdont
letypepeuttreassimiluntypeintgral.
12.2.1.Dclarationdestypestemplate
Les template quisontdestypesgnriquessontdclarsparlasyntaxesuivante:
template <class|typenamenom[=type]
[,class|typenamenom[=type]
[...]>
179
Chapitre12.Lestemplate
Exemple121.Dclarationdeparamtrestemplate
template <classT,typenameU,classV=int
>
Danscetexemple,T,UetVsontdestypesgnriques.Ilspeuventremplacernimportequeltypedu
langagedjdclaraumomentoladclaration template estfaite.Deplus,letypegnriqueVa
pourvaleurpardfautletypeentierint.Onvoitbiendanscetexemplequelesmotscls typename
et class peuventtreutilissindiffremment.
Lorsquondonnedesvaleurspardfautuntypegnrique,ondoitdonnerdesvaleurspardfaut
touslestypesgnriquesquilesuiventdansladclaration template.Lalignesuivanteprovoquera
doncuneerreurdecompilation:
template <classT=int,classV >
Danscetexemple,laclassetemplate Dictionnairepermetderelierdesclsleurslments.Cescls
etcesvaleurspeuventprendrenimportequeltype.Lesclsetlesvaleurssontstockesparalllement
danslesmembres Clef et Valeur .Cesmembressontenfaitdesconteneurs template,dontla
classeestgnriqueetdsigneparleparamtre templatetemplate C.Leparamtre template
deCestutilispourdonnerletypedesdonnesstockes,savoirlestypesgnriquesUetVdans
lecasdelaclasseDictionnaire.Enfin,laclasseDictionnairepeututiliserunconteneurpardfaut,qui
estlaclasse template Tableau.
Pourplusdedtailssurladclarationdesclasses template,voirlaSection12.3.2.
180
Chapitre12.Lestemplate
12.2.2.Dclarationdesconstantestemplate
Ladclarationdesparamtres template detypeconstantesefaitdelamaniresuivante:
template <typeparamtre[=valeur][,...]
>
typeintgral(char,wchar_t,int,long,shortetleursversionssignesetnonsignes)ounumr;
pointeurourfrencedobjet;
pointeurourfrencedefonction;
pointeursurmembre.
Cesontdonctouslestypesquipeuventtreassimilsdesvaleursentires(entiers,
adresses).
numrsou
Exemple123.Dclarationdeparamtrestemplatedetypeconstante
template <classT,inti,void(*f)(int)
>
12.3.Fonctionsetclassestemplate
template suit engnral ladclarationou
Aprsladclarationdunoudeplusieursparamtres
ladfinitiondunefonctionouduneclasse template. Danscettedfinition, lestypesgnriques
peuventtreutilissexactementcommesilsagissaitdetypesnormaux.Lesconstantes template
peuventtreutilisesdanslafonctionoulaclasse template commedesconstanteslocales.
12.3.1.Fonctionstemplate
Ladclarationet ladfinitiondesfonctions template sefait exactement commesi lafonction
taitunefonctionnormale, ceciprsquelledoittreprcdedeladclarationdesparamtres
template.Lasyntaxedunedclarationdefonction template estdonclasuivante:
template <paramtres_template>
typefonction(paramtres_fonction);
181
Chapitre12.Lestemplate
o paramtre_template estlalistedesparamtres template et paramtres_fonction estla
listedesparamtresdelafonction fonction. type estletypedelavaleurderetourdelafonction,
cepeuttreundestypesgnriquesdelalistedesparamtres template.
Touslesparamtres template quisontdestypesdoiventtreutilissdanslalistedesparamtresde
lafonction,moinsquuneinstanciationexplicitedelafonctionnesoitutilise.Celapermetaucom
pilateurderaliserlidentificationdestypesgnriquesaveclestypesutiliserlorsdelinstanciation
delafonction.VoirlaSection12.4pourplusdedtailscesujet.
Ladfinitiondunefonction template sefaitcommeunedclarationaveclecorpsdelafonction.
Ilestalorspossibledyutiliserlesparamtres template commesilstaientdestypesnormaux:
desvariablespeuventtredclaresavecuntypegnrique,etlesconstantestemplate peuventtre
utilisescommedesvariablesdfinieslocalement aveclaclassedestockageconst. Lesfonctions
template scriventdoncexactementcommedesfonctionsclassiques.
Exemple124.Dfinitiondefonctiontemplate
template <classT >
TMin(Tx,Ty)
{
returnx <y?x:y;
}
12.3.2.Lesclassestemplate
Ladclarationet ladfinitionduneclasse template sefont commecelles dunefonction
template : ellesdoivent treprcdesdeladclaration
template destypesgnriques. La
dclarationsuitdonclasyntaxesuivante:
template <paramtres_template>
class|struct|unionnom;
template
182
Chapitre12.Lestemplate
o paramtre_template reprsentelalistedesparamtres template delaclasse template
classe, nom reprsentelenomdelamthodedfinir,et
paramtres_mthode sesparamtres.
Il est absolument ncessairedanscecasdespcifier
touslesparamtres template delaliste
paramtres_template dansparamtres, sparspardesvirgules, afindecaractriserlefaitque
cest laclasse classe qui est template et quil nesagit pasdunemthode template dune
classenormale.Dunemaniregnrale,ilfaudratoujoursspcifierlestypesgnriquesdelaclasse
entrelessignesdinfrioritetdesupriorit, justeaprssonnom, chaquefoisquonvoudrala
rfrencer. Cettergleestcependantfacultativelorsquelaclasseestrfrencelintrieurdune
fonctionmembre.
Contrairementauxfonctions template nonmembres,lesmthodesdesclasses template peuvent
utiliserdestypesgnriquesdeleurclassesanspourautantquilssoientutilissdanslalistedeleurs
paramtres.Eneffet,lecompilateurdterminequelssontlestypesidentifierauxtypesgnriques
lorsdelinstanciationdelaclasse template,etnadoncpasbesoindeffectuercetteidentification
aveclestypesdesparamtresutiliss.VoirlaSection12.3.3pourplusdedtailscesujet.
Exemple125.Dfinitiondunepiletemplate
template <classT >
classStack
{
typedefstructstackitem
{
TItem;
//OnutiliseletypeTcomme
structstackitem*Next;//sictaituntypenormal.
}StackItem;
StackItem*Tete;
public:
//Lesfonctionsdelapile:
Stack(void);
Stack(constStack<T> &);
//Laclasseestrfrenceenindiquant
//sontypeentre < et > ("Stack<T>").
//Ici,cenestpasunencessit
//cependant.
~Stack(void);
Stack<T> &operator=(constStack<T> &);
voidpush(T);
Tpop(void);
boolis_empty(void)const;
voidflush(void);
};
//Pourlesfonctionsmembresdfiniesendehorsdeladclaration
//delaclasse,ilfautunedclarationdetypegnrique:
template <classT >
Stack<T>::Stack(void)//Laclasseestrfrenceenindiquant
//sontypeentre < et > ("Stack<T>").
//Cestimpratifendehorsdela
//dclarationdelaclasse.
{
Tete=NULL;
return;
}
183
Chapitre12.Lestemplate
184
Chapitre12.Lestemplate
template <classT >
voidStack<T>::push(TItem)
{
StackItem*tmp=newStackItem;
tmp>Item=Item;
tmp>Next=Tete;
Tete=tmp;
return;
}
template <classT >
TStack <T>::pop(void)
{
Ttmp;
StackItem*ptmp=Tete;
if(Tete!=NULL)
{
tmp=Tete>Item;
Tete=Tete >Next;
deleteptmp;
}
returntmp;
}
template <classT >
boolStack<T>::is_empty(void)const
{
return(Tete==NULL);
}
template <classT >
voidStack<T>::flush(void)
{
while(Tete!=NULL)pop();
return;
}
12.3.3.Fonctionsmembrestemplate
Lesdestructeursmispart, lesmthodesduneclassepeuventtre template, quelaclasseelle
mmesoit template ounon,pourvuquelaclassenesoitpasuneclasselocale.
Lesfonctionsmembres template peuventapparteniruneclasse
male.
template ouuneclassenor
Lorsquelaclasselaquelleellesappartiennentnestpas template,leursyntaxeestexactementla
mmequepourlesfonctions template nonmembre.
185
Chapitre12.Lestemplate
Exemple126.Fonctionmembretemplate
classA
{
inti;
//Valeurdelaclasse.
public:
template <classT >
voidadd(Tvaleur);
};
template <classT >
voidA::add(Tvaleur)
{
i=i+((int)valeur);
return;
}
//AjoutevaleurA::i.
Lesfonctionsmembresvirtuellesnepeuventpastretemplate.Siunefonctionmembre template
alemmenomquunefonctionmembrevirtuelleduneclassedebase, elleneconstituepasune
redfinitiondecettefonction.Parconsquent,lesmcanismesdevirtualitsontinutilisablesavecles
186
Chapitre12.Lestemplate
fonctionsmembres template.Onpeutcontournerceproblmedelamaniresuivante:ondfinira
unefonctionmembrevirtuellenon template quiappelleralafonctionmembre template.
Exemple128.Fonctionmembretemplateetfonctionmembrevirtuelle
classB
{
virtualvoidf(int);
};
classD:publicB
{
template <classT >
voidf(T);
//CettefonctionneredfinitpasB::f(int).
voidf(inti)
{
f<>(i);
return;
}
//CettefonctionsurchargeB::f(int).
//Elleappelledelafonctiontemplate.
};
Danslexempleprcdent,onestobligdeprciserquelafonctionappelerdanslafonctionvirtuelle
estlafonction template,etquilnesagitdoncpasdunappelrcursifdelafonctionvirtuelle.Pour
cela,onfaitsuivrelenomdelafonction template dunepairedesignesinfrieuretsuprieur.
Plusgnralement,siunefonctionmembre template duneclassepeuttrespcialiseenunefonc
tionquialammesignaturequuneautrefonctionmembredelammeclasse,etquecesdeuxfonc
tionsontlemmenom,touterfrencecenomutiliseralafonctionnon template.Ilestpossible
template
depasseroutrecettergle, conditiondedonnerexplicitementlalistedesparamtres
entrelessignesinfrieuretsuprieurlorsdelappeldelafonction.
Exemple129.Surchargedefonctionmembreparunefonctionmembretemplate
#include <iostream>
usingnamespacestd;
structA
{
voidf(int);
template <classT >
voidf(T)
{
cout << "Template" << endl;
}
};
//Fonctionnontemplate:
voidA::f(int)
{
cout << "Nontemplate" << endl;
}
//Fonctiontemplate:
187
Chapitre12.Lestemplate
template <>
voidA::f<int>(int)
{
cout << "Spcialisationf <int>" << endl;
}
intmain(void)
{
Aa;
a.f(1);
//Appeldelaversionnontemplatedef.
a.f(c); //Appeldelaversiontemplatedef.
a.f<>(1);//Appeldelaversiontemplatespcialisedef.
return0;
}
Pourplusdedtailssurlaspcialisationdes template,voirlaSection12.5.
12.4.Instanciationdestemplate
Ladfinitiondesfonctionsetdesclasses template negnreaucuncodetantquetouslesparamtres
template nontpasprischacununevaleurspcifique.Ilfautdonc,lorsdelutilisationdunefonction
ouduneclasse template,fournirlesvaleurspourtouslesparamtresquinontpasdevaleurpar
dfaut.Lorsquesuffisammentdevaleurssontdonnes,lecodeestgnrpourcejeudevaleurs.On
appellecetteoprationlinstanciationdestemplate.
Plusieurs possibilits sont offertes pour parvenir ce rsultat : linstanciationimplicite
linstanciationexplicite.
et
12.4.1.Instanciationimplicite
Linstanciationimpliciteestutiliseparlecompilateurlorsquilrencontreuneexpressionquiutilise
pourlapremirefoisunefonctionouuneclasse template,etquildoitlinstancierpourcontinuer
sontravail.Lecompilateursebasealorssurlecontextecourantpourdterminerlestypesdespara
mtres template utiliser.Siaucuneambigutnalieu,ilgnrelecodepourcejeudeparamtres.
Ladterminationdestypesdesparamtres template peutsefairesimplement,outredduitede
lexpressioncompiler.Parexemple,lesfonctionsmembres template sontinstanciesenfonction
templateMin dfiniedans
dutypedeleursparamtres. Silonreprendlexempledelafonction
lExemple124,cestsonutilisationdirectequiprovoqueuneinstanciationimplicite.
Exemple1210.Instanciationimplicitedefonctiontemplate
inti=Min(2,3);
188
Chapitre12.Lestemplate
inti=Min(2,3.0);
parcequelecompilateurnepeutpasdterminersiletypegnriqueTdoitprendrelavaleurintou
double. Ilyadoncuneerreur, saufsiunefonction Min(int,double) estdfiniequelquepart.
Pourrsoudrecetypedeproblme,ondevraspcifiermanuellementlesparamtres template dela
fonction,lorsdelappel.Ainsi,laligneprcdentecompilesionlarcritcommesuit:
inti=Min<int>(2,3.0);
//InstanciationdeA <char>.
//InstanciationdeA <char>::f().
189
Chapitre12.Lestemplate
12.4.2.Instanciationexplicite
Linstanciationexplicitedes template est unetechniquepermettant auprogrammeur deforcer
linstanciationdes template danssonprogramme.Pourraliseruneinstanciationexplicite,ilfaut
spcifierexplicitementtouslesparamtres template utiliser.Celasefaitsimplementendonnant
ladclarationdu template,prcdeparlemotcl template :
templatenom<valeur[,valeur[...]]>;
Parexemple, pourforcerlinstanciationdunepiletellequecelledfiniedanslExemple125,
faudraprciserletypedeslmentsentrecrochetsaprslenomdelaclasse:
templateStack<int>;
il
//InstancielaclasseStack<int>.
Cettesyntaxepeuttresimplifiepourlesfonctions template,conditionquetouslesparamtres
template puissenttredduitsparlecompilateurdestypesdesparamtresutilissdansladclara
tiondelafonction.Ainsi,ilestpossibledeforcerlinstanciationdelafonction templateMindela
maniresuivante:
templateintMin(int,int);
Danscetexemple,lafonction templateMinestinstanciepourletypeint,puisquesesparamtres
sontdecetype.
Lorsquunefonctionouuneclassetemplate adesvaleurspardfautpoursesparamtrestemplate,
ilnestpasncessairededonnerunevaleurpourcesparamtres.Sitouteslesvaleurspardfautsont
utilises, lalistedesvaleurspeut trevide(maislessignesdinfrioritet
desuprioritdoivent
malgrtouttreprsents).
Exemple1211.Instanciationexplicitedeclassetemplate
template<classT=char>
classChaine;
templateChaine<>;
//InstanciationexplicitedeChaine
<char>.
12.4.3.Problmessoulevsparlinstanciationdes
template
Les template doiventimprativementtredfinislorsdeleurinstanciationpourquelecompila
teurpuissegnrerlecodedelinstance.Celasignifiequelesfichiersdenttedoiventcontenirnon
seulementladclaration,maisgalementladfinitioncompltedes template.Celaaplusieursin
convnients.Lepremierestbienentenduquelonnepeutpasconsidrerles template commeles
fonctionsetlesclassesnormalesdulangage,pourlesquelsilestpossibledesparerladclarationde
ladfinitiondansdesfichiersspars.Ledeuximeinconvnientestquelesinstancesdes template
sontcompilesplusieursfois,cequidiminuedautantpluslesperformancesdescompilateurs.Enfin,
cequiestleplusgrave,cestquelesinstancesdes template sontenmultiplesexemplairesdansles
fichiersobjetsgnrsparlecompilateur,etaccroissentdonclatailledesfichiersexcutableslissue
190
Chapitre12.Lestemplate
delditiondeliens.Celanestpasgnantpourlespetitsprogrammes,maispeutdevenirrdhibitoire
pourlesprogrammesassezgros.
Lepremierproblmenestpastropgnant,carilrduitlenombredefichierssources,cequinesten
gnralpasunemauvaisechose.Notezgalementqueles template nepeuventpastreconsidrs
commedesfichierssourcesclassiques,puisquesansinstanciation,ilsnegnrentaucuncodemachine
(cesontdesclassesdeclasses,oumtaclasses).Maisceproblmepeutdevenirennuyantdans
lecasdebibliothques template critesetvenduespardessocitsdsireusesdeconserverleur
savoirfaire.Pourrsoudreceproblme,lelangagedonnelapossibilitdexporterlesdfinitionsdes
template dansdesfichierscomplmentaires.NousverronslamaniredeprocderdanslaSection
12.7.
Ledeuximeproblmepeuttrersoluaveclexportationdestemplate,oupartoutautretechnique
doptimisationdescompilateurs.Actuellement,laplupartdescompilateurssontcapablesdegnrer
desfichiersdentteprcompils,quicontiennentlersultatdelanalysedesfichiersdenttedj
lus.Cettetechniquepermetdediminuerconsidrablementlestempsdecompilation,maisncessite
souventdutilisertoujourslemmefichierdentteaudbutdesfichierssources.
Letroisimeproblmeestengnralrsolupardestechniquesvaries,quincessitentdestraitements
complexesdanslditeurdeliensoulecompilateur.Latechniquelaplussimple,utiliseparlaplupart
descompilateursactuels, passeparunemodificationdelditeurdelienspourquil regroupeles
diffrentesinstancesdesmmes template. Dautrescompilateurs, plusrares, grentunebasede
donnesdanslaquellelesinstancesde template gnreslorsdelacompilationsontstockes.Lors
delditiondeliens,lesinstancesdecettebasesontajouteslalignedecommandedelditeurde
liensafindersoudrelessymbolesnondfinis.Enfin,certainscompilateurspermettentdedsactiver
lesinstanciationsimplicitesdes template.Celapermetdelaisserauprogrammeurlaresponsabilit
delesinstanciermanuellement, laidedinstanciationsexplicites. Ainsi, les template peuvent
ntredfiniesquedansunseulfichiersource,rservceteffet.Cettederniresolutionestdeloin
laplussre,etilestdoncrecommanddcrireuntelfichierpourchaqueprogramme.
Ce paragraphe vous a prsent trois des principauxproblmes soulevs par lutilisationdes
template, ainsi quelessolutionslespluscourantesqui
yont tapportes. Il est vivement
recommanddeconsulterladocumentationfournieaveclenvironnementdedveloppementutilis,
afinlafoisderduirelestempsdecompilationetdoptimiserlesexcutablesgnrs.
12.5.Spcialisationdestemplate
Jusquprsent,nousavonsdfinilesclassesetlesfonctions template dunemanireunique,pour
touslestypesettouteslesvaleursdesparamtres template.Cependant,ilpeuttreintressantde
dfiniruneversionparticulireduneclasseoudunefonctionpourunjeuparticulierdeparamtres
template.
Parexemple, lapiledelExemple125peut treimplmentebeaucoupplusefficacement si elle
stockedespointeurspluttquedesobjets,saufsilesobjetssontpetits(ouappartiennentundestypes
prdfinisdulangage).Ilpeuttreintressantdemanipulerlespointeursdemaniretransparenteau
niveaudelapile,pourquelamthode pop renvoietoujoursunobjet,quelapilestockedespointeurs
oudesobjets.Afinderalisercela,ilfautdonnerunedeuximeversiondelapilepourlespointeurs.
LeC++permettoutcela:lorsquunefonctionouuneclasse template atdfinie,ilestpossible
delaspcialiserpouruncertainjeudeparamtres template.Ilexistedeuxtypesdespcialisation:
lesspcialisationstotales,quisontlesspcialisationspourlesquellesilnyaplusaucunparamtre
template (ilsonttousunevaleurbiendtermine),etlesspcialisationspartielles,pourlesquelles
seulsquelquesparamtres template ontunevaleurfixe.
191
Chapitre12.Lestemplate
12.5.1.Spcialisationtotale
Lesspcialisationstotalesncessitentdefournirlesvaleursdesparamtres template,sparespar
desvirgulesetentrelessignesdinfrioritetdesupriorit,
aprslenomdelafonctionoudela
classe template.Ilfautfaireprcderladfinitiondecettefonctionoudecetteclasseparlaligne
suivante:
template <>
quipermetdesignalerquelalistedesparamtres
doncquelaspcialisationesttotale).
template pourcettespcialisationestvide(et
//Clefpermettantderetrouverdesdonnes.
//Pointeursurlesdonnes.
template <>
StructureMin<Structure>(Structures1,Structures2)
{
if(s1.Clef>s2.Clef)
returns1;
else
returns2;
}
template ne
Note:Pourquelquescompilateurs,lalignedclarantlalistevidedesparamtres
doitpastrecrite.Ondoitdoncfairedesspcialisationstotalesanslemotcl template.Ce
comportementnestpasceluispcifiparlanorme,etlecodecritpourcescompilateursnest
doncpasportable.
12.5.2.Spcialisationpartielle
Lesspcialisationspartiellespermettentdedfinirlimplmentationdunefonctionouduneclasse
template pourcertainesvaleursdeleursparamtres template et degarderdautresparamtres
indfinis.Ilestmmepossibledechangerlanaturedunparamtre template (cestdireprciser
sil sagit dunpointeurounon)et deforcerlecompilateurprendreuneimplmentationplutt
quuneautreselonquelavaleurutilisepourceparamtreestellemmeunpointeurounon.
template
Commepourlesspcialisationstotales,ilestncessairededclarerlalistedesparamtres
utilissparlaspcialisation.Cependant,ladiffrencedesspcialisationstotales,cettelistenepeut
plustrevide.
192
Chapitre12.Lestemplate
Exemple1213.Spcialisationpartielle
//Dfinitionduneclassetemplate:
template <classT1,classT2,intI >
classA
{
};
//Spcialisationn 1delaclasse:
template <classT,intI >
classA <T,T*,I >
{
};
//Spcialisationn 2delaclasse:
template <classT1,classT2,intI >
classA <T1*,T2,I >
{
};
//Spcialisationn 3delaclasse:
template <classT >
classA <int,T*,5 >
{
};
//Spcialisationn 4delaclasse:
template <classT1,classT2,intI >
classA <T1,T2*,I >
{
};
template peut
Onnoteraquelenombredesparamtres template dclarslasuitedumotcl
varier, maisquelenombredevaleursfourniespourlaspcialisationest
toujoursconstant (dans
lexempleprcdent,ilyenatrois).
Lesvaleursutilisesdanslesidentificateurstemplate desspcialisationsdoiventrespecterlesrgles
suivantes:
unevaleurnepeutpastreexprimeenfonctiondunparamtre
template delaspcialisation;
//Erreur!
//Spcialisationincorrecte!
letypedunedesvaleursdelaspcialisationnepeutpasdpendredunautreparamtre;
template <classT,Tt >
structC
{
};
193
Chapitre12.Lestemplate
lalistedesargumentsdelaspcialisationnedoitpastreidentiquelalisteimplicitedeladcla
ration template correspondante.
12.5.3.Spcialisationdunemthodeduneclassetemplate
Laspcialisationpartielleduneclassepeutparfoistreassezlourdeemployer,enparticuliersila
structurededonnesquellecontientnechangepasentrelesversionsspcialises.Danscecas,ilpeut
treplussimpledenespcialiserquecertainesmthodesdelaclasseetnonlaclassecomplte.Cela
permetdeconserverladfinitiondesmthodesquinontpaslieudtremodifiespourlesdiffrents
types,etdviterdavoirredfinirlesdonnesmembresdelaclasselidentique.
Lasyntaxepermettantdespcialiserunemthodeduneclasse template esttrssimple. Ilsuffit
template normale, etdelaspcialiseren
eneffetdeconsidrerlamthodecommeunefonction
prcisantlesparamtres template utiliserpourcettespcialisation.
Exemple1214.Spcialisationdefonctionmembredeclassetemplate
#include <iostream>
usingnamespacestd;
template <classT >
classItem
{
Titem;
public:
Item(T);
voidset(T);
Tget(void)const;
voidprint(void)const;
};
template <classT >
Item<T>::Item(Ti)
{
item=i;
}
//Accesseurs:
template <classT >
voidItem<T>::set(Ti)
{
item=i;
}
194
//Constructeur
Chapitre12.Lestemplate
template <classT >
TItem <T>::get(void)const
{
returnitem;
}
//Fonctiondaffichagegnrique:
template <classT >
voidItem<T>::print(void)const
{
cout << item << endl;
}
//Fonctiondaffichagespcialiseexplicitementpourletypeint*
//etlamthodeprint:
template <>
voidItem<int* >::print(void)const
{
cout << *item << endl;
}
12.6.Motcltypename
Nousavonsdjvuquelemotcl typename pouvaittreutilispourintroduirelestypesgnriques
danslesdclarations template.Cependant,ilpeuttreutilisdansunautrecontextepourintroduire
lesidentificateursdetypesinconnusdansles template.Eneffet,untypegnriquepeuttrsbien
treuneclassedfinieparlutilisateur,lintrieurdelaquelledestypessontdfinis.Afindepouvoir
utilisercestypesdanslesdfinitionsdes template,ilestncessairedutiliserlemotcl typename
pourlesintroduire,carapriorilecompilateurnesaitpasqueletypegnriquecontientladfinition
dunautretype.Cemotcldoittreplacavantlenomcompletdutype:
typenameidentificateur
Le mot cl typename est donc utilis pour signaler au compilateur que lidentificateur
identificateur estuntype.
Exemple1215.Motcltypename
classA
{
public:
typedefintY;
};
template <classT >
classX
{
typenameT::Yi;
//YestuntypedfinidanslaclasseA.
//LaclassetemplateXsupposequele
//typegnriqueTdfinisseuntypeY.
};
195
Chapitre12.Lestemplate
X<A> x;
//Apeutservirinstancieruneclasse
//partirdelaclassetemplateX.
12.7.Fonctionsexportes
Commeonlavu, lesfonctionsetclasses template sonttoutesinstancieslorsquellessontren
contrespourlapremirefoisparlecompilateuroulorsquelalistedeleursparamtresestfournie
explicitement.
Cettergleauneconsquencemajeure:ladfinitioncompltedesfonctionsetdesclasses template
doittreinclusedanschacundesfichiersdanslequelellessontutilises.Engnral,lesdclarationset
lesdfinitionsdesfonctionsetdesclasses template sontdoncregroupesensembledanslesfichiers
dentte(etlecodenesetrouvepasdansunfichierC++).Celaestlafoistrslent(ladfinitiondoit
trerelueparlecompilateurchaquefoisquun template estutilis)etnepermetpasdeprotgerle
savoirfairedesentreprisesquiditentdesbibliothques template,puisqueleurcodeestaccessible
toutlemonde.
Afindersoudreces problmes, leC++permet decompiler les fonctions et les classes
template, et ainsi dviterlinclusionsystmatiquedeleurdfinitiondanslesfichierssources.
Cettecompilationsefaitlaidedumotcl export.
Pourparvenircersultat, vousdevezdclarer export lesfonctionsetlesclasses template
concernes. Ladclarationduneclasse templateexportrevient dclarer export toutesses
fonctionsmembresnon inline,toutessesdonnesstatiques,toutessesclassesmembresettoutes
sesfonctionsmembres template nonstatiques.Siunefonction template estdclarecommetant
inline,ellenepeutpastredetype export.
Lesfonctionsetlesclasses template quisontdfiniesdansunespacedenommageanonymene
peuventpastredclares export.VoirleChapitre11plusdedtailssurlesespacesdenommage.
Exemple1216.Motclexport
exporttemplate <classT >
voidf(T);
//Fonctiondontlecodenestpasfourni
//danslesfichiersquilutilisent.
196
II.LabibliothquestandardC++
ToutcommepourlelangageC,pourlequeluncertainnombredefonctionsonttdfiniesetstandar
disesetconstituentlabibliothqueC,unebibliothquedeclassesetdefonctionsatspcifiepour
lelangageC++. Cettebibliothqueestlersultatdelvolutiondeplusieursbibliothques, parfois
dveloppesindpendammentparplusieursfournisseursdenvironnementsC++,quionttfusion
nesetnormalisesafindegarantirlaportabilitdesprogrammesquilesutilisent.Unedesprinci
palesbriquesdecettebibliothqueestsansaucundoutelaSTL(abrviationdeStandardTemplate
Library),telpointquilyasouventconfusionentrelesdeux.
CettepartieapourbutdeprsenterlesprincipalesfonctionnalitsdelabibliothquestandardC++.
Bienentendu,ilesthorsdequestiondedcrirecompltementchaquefonctionouchaquedtaildu
fonctionnementdelabibliothquestandard,carcelarendraitillisiblesetincomprhensibleslesex
plications.Cependant,lesinformationsdebasevousserontdonnesafindevouspermettredutiliser
efficacement labibliothquestandardC++et decomprendrelesfonctionnalitslesplusavances
lorsquevousvousyintresserez.
LabibliothquestandardC++estrellementunsujetdetaille. titreindicatif, sadescriptionest
aussivolumineusequecelledulangageluimmedanslanormeC++.Maiscenestpastout,ilfaut
imprativementavoircomprisenprofondeurlesfonctionnalitslesplusavancesduC++pourappr
hendercorrectementlabibliothquestandard.Enparticulier,touslesalgorithmesettouteslesclasses
fourniesparlabibliothquesontsusceptiblesdetravaillersurdesdonnesdetypearbitraire.Labi
bliothqueutilisedonccompltementlanotiondetemplate,etsebasesurplusieursabstractionsdes
donnesmanipulesetdeleurstypesafinderendregnriquelimplmentationdesfonctionnalits.
Deplus,labibliothqueutiliselemcanismedesexceptionsafindesignalerleserreursquipeuventse
produirelorsdelexcutiondesmthodesdesesclassesetdesesfonctions.Enfin,uncertainnombre
denotionsalgorithmiquesavancessontutilisesdanstoutelabibliothque.Laprsentationquisera
faiteseradoncprogressive,toutenessayantdeconserverunordrelogique.Toutcommepourlapar
tieprcdente,ilestprobablequeplusieurslecturesserontncessairesauxdbutantspourassimiler
touteslessubtilitsdelabibliothque.
Lepremierchapitredecettepartie(Chapitre13)prsentelesnotionsdebasequisontutilisesdans
toutelalibraire:encapsulationdesfonctionsdelabibliothqueCclassique,classesdetraitspourles
typesdebase,notionditrateurs,defoncteurs,dallocateursmmoireetdecomplexitalgorithmique.
LeChapitre14prsentelestypescomplmentairesquelabibliothquestandardC++dfinit
pour
faciliterlavieduprogrammeur. Leplusimportantdecestypesestsansdoutelaclassedegestion
deschanesdecaractresbasic_string.LeChapitre15prsentelesnotionsdefluxdentre/sortie
standards, et lanotiondetamponpourcesflux. Lesmcanismesdelocalisation(cestdireles
fonctionsdeparamtrageduprogrammeenfonctiondesconventionsetdesprfrencesnationales)
serontdcritsdansleChapitre16.LeChapitre17estsansdoutelundesplusimportants,puisquil
prsentetouslesconteneursfournisparlabibliothquestandard. Enfin, leChapitre18dcrit les
principauxalgorithmesdelabibliothque,quipermettentdemanipulerlesdonnesstockesdansles
conteneurs.
LesinformationsdcritesicisontbasessurlanormeISO14882dulangageC++,etnonsurlaralit
desenvironnementsC++actuels.Ilestdoncfortementprobablequebonnombredexemplesfournis
icinesoientpasutilisablestelsquelssurlesenvironnementsdedveloppementexistantssurlemar
ch,bienqueloncommencevoirapparatredesenvironnementspresquetotalementrespectueuxde
lanormemaintenant.Delgresdiffrencesdanslinterfacedesclassesdcritespeuventgalement
apparatreetncessiterlamodificationdecesexemples.Cependant,terme,touslesenvironnements
dedveloppementrespecterontlesinterfacesspcifiesparlanorme,etlesprogrammesutilisantla
bibliothquestandardserontrellementportablesauniveausource.
Chapitre13.Servicesetnotionsdebasedela
bibliothquestandard
LabibliothquestandardC++fournit uncertainnombredefonctionnalitsdebasesurlesquelles
touteslesautresfonctionnalitsdelabibliothquesappuient.
Cesfonctionnalitsapparaissent
commedesclassesdencapsulationdelabibliothqueCetdesclassesdabstractiondesprincipales
constructionsdulangage. Cesderniresutilisent desnotionstrsvoluespour permettreune
encapsulationrellementgnriquedestypesdebase.Dautrepart,labibliothquestandardutilise
lanotiondecomplexitalgorithmiquepourdfinirlescontraintesdeperformancedesoprations
ralisablessursesstructuresdedonnesainsiquesursesalgorithmes. Bienquecomplexes, toutes
cesnotionssontomniprsentesdanstoutelabibliothque,aussiestilextrmementimportantdeles
comprendreendtail.Cechapitreapourbutdevouslesprsenteretdelesclaircir.
13.1.EncapsulationdelabibliothqueCstandard
LabibliothqueCdfinitungrandnombredefonctionsCstandards, quelabibliothquestandard
C++reprendsoncompteetcompltepartoutessesfonctionnalitsavances.Pourbnficierdeces
fonctions,ilsuffitsimplementdinclurelesfichiersdenttedelabibliothqueC,toutcommeonle
faisaitaveclesprogrammesCclassiques.
Toutefois,lesfonctionsainsidclaresparcesenttesapparaissentdanslespacedenommageglobal,
cequirisquedeprovoquerdesconflitsdenomsavecdesfonctionshomonymes(rappelonsqueles
fonctionsCnesontpassurchargeables).Parconsquent,etdansunsoucidhomognitaveclereste
desfonctionnalitsdelabibliothqueC++,unjeudenttescomplmentairesatdfinipourles
fonctionsdelabibliothqueC.Cesenttesdfinissenttousleurssymbolesdanslespacedenommage
std::,quiestrservpourlabibliothquestandardC++.
CesenttessedistinguentdesfichiersdenttedelabibliothqueCparlefaitquilsneportentpas
dextension .h etparlefaitqueleurnomestprfixparlalettrec.Lesenttesutilisablesainsisont
donclessuivants:
cassert
cctype
cerrno
cfloat
ciso646
climits
clocale
cmath
csetjmp
csignal
cstdarg
cstddef
cstdio
cstdlib
cstring
ctime
cwchar
cwctype
Parexemple, onpeutrcrirenotretoutpremierprogrammequelonafaitlaSection1.9dela
maniresuivante:
#include <cstdio>
199
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
longdoublex,y;
intmain(void)
{
std::printf("Calculdemoyenne\n");
std::printf("Entrezlepremiernombre:");
std::scanf("%Lf",&x);
std::printf("\nEntrezledeuximenombre:");
std::scanf("%Lf",&y);
std::printf("\nLavaleurmoyennede%Lfetde%Lfest%Lf.\n",
x,y,(x+y)/2);
return0;
}
Note:Lutilisationsystmatiqueduprfixestd:: peuttrenervantesurlesgrandsprogrammes.
Onauradoncintrt soit utiliserlesfichiersdentteclassiquesdelabibliothqueC, soit
inclureunedirective usingnamespacestd; pourintgrerlesfonctionnalitsdelabibliothque
standarddanslespacedenommageglobal.
Remarquezquelanormenesupposepasquecesenttessoientdesfichiersphysiques.Les
dclarationsquilssont suppossfairepeuvent donctreraliseslavoleparlesoutilsde
dveloppement,etvousnelestrouverezpasforcmentsurvotredisquedur.
CertainesfonctionnalitsfourniesparlabibliothqueConttencapsulesdansdesfonctionnalits
quivalentesdelabibliothquestandardC++.Cestnotammentlecaspourlagestiondeslocaleset
lagestiondecertainstypesdedonnescomplexes.Cestgalementlecaspourladterminationdes
limitesdereprsentationquelestypesdebasepeuventavoir.Classiquement,ceslimitessontdfinies
pardesmacrosdanslesenttesdelabibliothqueC,maisellessontgalementaccessiblesautravers
delaclasse template numeric_limits,dfiniedanslentte limits :
//Typesdarrondispourlesflottants:
enumfloat_round_style
{
round_indeterminate
=1,
round_toward_zero
= 0,
round_to_nearest
= 1,
round_toward_infinity
=2,
round_toward_neg_infinity=3
};
template <classT >
classnumeric_limits
{
public:
staticconstboolis_specialized=false;
staticTmin()throw();
staticTmax()throw();
staticconstintdigits =0;
staticconstintdigits10=0;
staticconstboolis_signed =false;
staticconstboolis_integer=false;
staticconstboolis_exact =false;
staticconstintradix=0;
staticTepsilon()throw();
200
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
staticTround_error()throw();
staticconstintmin_exponent =0;
staticconstintmin_exponent10=0;
staticconstintmax_exponent =0;
staticconstintmax_exponent10=0;
staticconstboolhas_infinity =false;
staticconstboolhas_quiet_NaN=false;
staticconstboolhas_signaling_NaN=false;
staticconstboolhas_denorm
=false;
staticconstboolhas_denorm_loss =false;
staticTinfinity()throw();
staticTquiet_NaN()throw();
staticTsignaling_NaN()throw();
staticTdenorm_min()throw();
staticconstboolis_iec559 =false;
staticconstboolis_bounded=false;
staticconstboolis_modulo =false;
staticconstbooltraps
=false;
staticconstbooltinyness_before=false;
staticconstfloat_round_style
round_style=round_toward_zero;
};
Ceprogrammedexempledterminelepluspetitetleplusgrandnombrereprsentableavecletype
entierint,ainsiquelenombredebitsutilisspourcoderleschiffresetlenombremaximaldechiffres
quelesnombresenbase10peuventavoirentantsrdepouvoirtrestockstelsquels.
13.2.Dfinitiondesexceptionsstandards
Labibliothquestandardutiliselemcanismedesexceptionsdulangagepoursignalerleserreursqui
peuventseproduirelexcutionauseindesesfonctions.Elledfinitpourcelauncertainnombre
declassesdexceptionsstandards,quetouteslesfonctionnalitsdelabibliothquesontsusceptibles
dutiliser.Cesclassespeuventtreutilisestellesquellesouservirdeclassesdebasedesclasses
dexceptionspersonnalisespourvospropresdveloppements.
201
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
Cesclassesdexceptionsontpresquetoutesdclaresdanslentte stdexcept, etdriventdela
classedebaseexception.Cettedernirenestpasdclaredanslemmeentteetnestpasutilise
directement,maisfournitlesmcanismesdebasedetouteslesexceptionsdelabibliothquestandard.
Elleestdclarecommesuitdanslentte exception :
classexception
{
public:
exception()throw();
exception(constexception&)throw();
exception&operator=(constexception&)throw();
virtual~exception()throw();
virtualconstchar*what()constthrow();
};
Notezquelexceptionbad_alloclanceparlesgestionnairesdemmoirelorsqueloprateur new ou
loprateur new[] napasrussifaireuneallocationnestpasdclaredanslentte stdexcept
nonplus.Sadclarationatplaceaveccelledesoprateursdallocationmmoire,danslentte
new.Cetteclassedrivetoutefoisdelaclasseexception,commelemontresadclaration:
classbad_alloc:publicexception
{
public:
bad_alloc()throw();
bad_alloc(constbad_alloc&)throw();
bad_alloc&operator=(constbad_alloc&)throw();
virtual~bad_alloc()throw();
virtualconstchar*what()constthrow();
};
202
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
Lesautresexceptionssontclassesendeuxgrandescatgories.Lapremirecatgorieregroupetoutes
lesexceptionsdontlapparitiontraduitsansdouteuneerreurdeprogrammationdansleprogramme,
carellesnedevraientjamaisseproduirelexcution.Ilsagitdesexceptionsditesderreursdans
lalogiqueduprogrammeet,entantquetelles,driventdelaclassedexceptionlogic_error.Cette
classeestdclarecommesuitdanslentte stdexcept :
classlogic_error:publicexception
{
public:
logic_error(conststring&what_arg);
};
Ellenecontientquunconstructeur,permettantdedfinirlachanedecaractresquiserarenvoye
parlamthodevirtuelle what. Ceconstructeurprendenparamtrecettechanedecaractressous
laformedunobjetdelaclassestring. Cetteclasseestdfinieparlabibliothquestandardafinde
faciliterlamanipulationdeschanesdecaractresetseradcriteplusendtaildanslaSection14.1.
Lesclassesdexceptionquidriventdelaclasselogic_errordisposentgalementdunconstructeur
similaire.Cesclassessontlessuivantes:
laclassedomain_error,quispcifiequunefonctionatappeleavecdesparamtressurlesquels
ellenest pasdfinie. Il faut contrlerlesvaleursdesparamtresutiliseslorsdelappel
dela
fonctionquialanccetteexception;
laclasselength_error,quiindiquequundpassementdecapacitmaximaledunobjetatralis.
Cesdpassementsseproduisentdanslesprogrammesbogus,quiessaientdutiliserunefonction
nalitaudeldeslimitesquiavaienttfixespourelle;
laclasseout_of_range,quispcifiequunevaleursitueendehorsdelaplagedevaleursautorises
atutilise.Cetypederreursignifiesouventquelesparamtresutilisspourunappeldefonction
nesontpascorrectsoupasinitialiss,etquilfautvrifierleurvalidit.
Ladeuximecatgoriedexceptionscorrespondauxerreursquinepeuventpastoujourstrecorriges
lorsdelcritureduprogramme, etquifontdoncpartiedesvnementsnaturelsquiseproduisent
lorsdesonexcution.Ellescaractrisentleserreursdexcution,etdriventdelaclassedexception
runtime_error.Cetteclasseestdclaredelamaniresuivantedanslentte stdexcept :
classruntime_error:publicexception
{
public:
runtime_error(conststring&what_arg);
};
Ellesutiliseexactementcommelaclasselogic_error.
Lesexceptionsdelacatgoriedeserreursdexcutionsontlessuivantes:
laclasserange_error,quisignifiequunevaleurestsortiedelaplagedevaleursdanslaquelleelle
devaitsetrouversuiteundbordementinternelabibliothque;
203
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
laclasseoverflow_error,quisignifiequundbordementparvaleurssuprieuressestproduitdans
uncalculinternelabibliothque;
laclasseunderflow_error,quisignifiequundbordementparvaleursinfrieuressestproduitdans
uncalculinternelabibliothque.
13.3.Abstractiondestypesdedonnes:lestraits
Uncertainnombredeclassesoudalgorithmespeuventmanipulerdestypesayantunesignification
particulire. Parexemple, laclassestring, quenousverronsplusloin, manipuledesobjetsdetype
caractre. Enralit, cesclasseset cesalgorithmespeuvent travailleravecnimportequelstypes
pourvuquetouscestypessecomportentdelammemanire.LabibliothquestandardC++utilise
donclanotiondetraits, quipermetdedfinirlescaractristiquesdecestypes. Lestraitssont
dfinisdansdesclassesprvuescetusage.Lesclassesetlesalgorithmesstandardsnutilisentque
lesclassesdetraitspourmanipulerlesobjets, garantissantainsiuneabstractiontotalevisvisde
leurstypes.Ainsi,ilsuffitdecoderunespcialisationdelaclassedestraitspouruntypeparticulier
afindepermettresonutilisationdanslesalgorithmesgnriques.Labibliothquestandarddfinitbien
entendudesspcialisationspourlestypesdebasedulangage.
Parexemple,laclassededfinitiondestraitsdestypesdecaractresestlaclassetemplatechar_traits.
Ellecontientlesdfinitionsdestypessuivants:
letypechar_type,quiestletypereprsentantlescaractreseuxmmes;
letypeint_type,quiestuntypecapabledecontenirtouteslesvaleurspossiblespourlescaractres,
ycomprislavaleurspcialedumarqueurdefindefichier;
letypeoff_type,quiestletypepermettantdereprsenterlesdplacementsdansunesquencede
caractres,ainsiquelespositionsabsoluesdanscettesquence.Cetypeestsigncarlesdplace
mentspeuventtreralissaussibienversledbutdelasquencequeverslafin;
letypepos_type,quiestunsoustypedutypeoff_type,etquinestutilisquepourlesdplacements
danslesfonctionsdepositionnementdesfluxdelabibliothquestandard;
letypestate_type,quipermetdereprsenterltatcourantdunesquencedecaractresdansles
fonctionsdeconversion. Cetypeestutilisdanslesfonctionsdetranscodagedessquencesde
caractresdunencodageversunautre.
204
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
labibliothquestandardqui manipulent lessquencesdecaractresdoivent doncstockerle
contextecourantlorsdelanalysedecessquences.Elleslefontgrceautypestate_typedela
classedestraitsdecescaractres.
Lexemplesuivantvouspermettradevrifierqueletypechar_typedelaclassededfinitiondestraits
pourletypecharestbienentenduletypecharluimme:
#include <iostream>
#include <typeinfo>
#include <string>
usingnamespacestd;
intmain(void)
{
//Rcuprelesinformationsdetypagedestraits:
consttype_info&ti_trait=
typeid(char_traits<char>::char_type);
//Rcuprelesinformationsdetypagedirectement:
consttype_info&ti_char=typeid(char);
//Comparelestypes:
cout << "Lenomdutypecaractredestraitsest:" <<
ti_trait.name() << endl;
cout << "Lenomdutypecharest:" <<
ti_char.name() << endl;
if(ti_trait==ti_char)
cout << "Lesdeuxtypessontidentiques."
<< endl;
else
cout << "Cenestpaslemmetype." << endl;
return0;
}
Laclassechar_traitsdfinitgalementuncertainnombredemthodestravaillantsurlestypesde
caractresetpermettantderaliserlesoprationsdebasesurcescaractres.Cesmthodespermettent
essentiellementdecomparer,decopier,dedplaceretderechercherdescaractresdansdessquences
decaractres,entenantcomptedetouteslescaractristiquesdecescaractres.Ellecontientgalement
ladfinitiondelavaleurspcialeutilisedanslessquencesdecaractrespourmarquerlesfindeflux
( EOF ,abrviationdelanglaisEndOfFile).
Parexemple,leprogrammesuivantpermetdafficherlavaleurutilisepourspcifierunefindefichier
dansunesquencedecaractresdetypewchar_t:
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
char_traits<wchar_t>::int_typewchar_eof=
char_traits<wchar_t>::eof();
cout << "Lavaleurdefindefichierpourwchar_test:"
<< wchar_eof << endl;
205
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
return0;
}
Lesautresmthodesdelaclassededfinitiondestraitsdescaractres,ainsiquelesclassesded
finitiondestraitsdesautretypes,neserontpasdcritesplusendtailici.Ellessontessentiellement
utilisesauseindesalgorithmesdelabibliothquestandardetnontdoncquunintrtlimitpour
lesprogrammeurs,maisilestimportantdesavoirquellesexistent.
13.4.Abstractiondespointeurs:lesitrateurs
Labibliothquestandarddfinituncertainnombredestructuresdedonnesvolues,quipermettent
destockeretdemanipulerlesobjetsutilisateurdemanireoptimale,vitantainsiauprogrammeur
davoirrinventerlaroue. Onappellecesstructuresdedonnesdesconteneurs. Cesconteneurs
peuventtremanipulsautraversdefonctionsspciales,selonungrandnombredalgorithmespos
siblesdontlabibliothquedisposeenstandard.Lensembledesfonctionnalitsfourniesparlabiblio
thquepermetdesubveniraubesoindesprogrammeursdanslamajoritdescas.Nousdtailleronsla
notiondeconteneuretlesalgorithmesdisponiblesplusloindanscedocument.
Lamaniredaccderauxdonnesdesconteneursdpendbienentendudeleurnatureetdeleurstruc
ture.Celasignifiequenthorie,ilestncessairedespcialiserlesfonctionspermettantdappliquer
lesalgorithmespourchaquetypedeconteneurexistant.Cettetechniquenestnipratique,niexten
sible,puisquelesalgorithmesfournisparlabibliothquenepourraientdanscecaspastravaillersur
desconteneurscritsparleprogrammeur.Cestpourcetteraisonquelabibliothquestandardutilise
uneautretechniquepouraccderauxdonnesdesconteneurs.Cettetechniqueestbasesurlanotion
ditrateur.
13.4.1.Notionsdebaseetdfinition
Unitrateurnestriendautrequunobjetpermettantdaccdertouslesobjetsdunconteneurdonn,
souventsquentiellement,selonuneinterfacestandardise.Ladnominationditrateurprovientdonc
dufaitquelesitrateurspermettentditrersurlesobjetsdunconteneur,cestdiredenparcourir
lecontenuenpassantpartoussesobjets.
Commelesitrateurssontdesobjetspermettantdaccderdautresobjets,ilsnereprsententpas
euxmmescesobjets,maispluttlemoyendelesatteindre.Ilssontdonccomparablesauxpointeurs,
dont ilsont exactement lammesmantique. Enfait, lesconcepteursdelabibliothquestandard
sesontbasssurcettepropritpourdfinirlinterfacedesitrateurs, quisontdoncuneextension
*i ou
delanotiondepointeur. Parexemple, ilestpossibledcriredesexpressionstellesque
++i avecunitrateur i.Touslesalgorithmesdelabibliothque,quitravaillentnormalementsur
desitrateurs,sontdoncsusceptiblesdefonctionneravecdespointeursclassiques.
Bienentendu,pourlaplupartdesconteneurs,lesitrateursnesontpasdesimplespointeurs,maisdes
objetsquisecomportentcommedespointeursetquisontspcifiqueschaqueconteneur.Ainsi,les
algorithmessontcritsdemanireuniforme,etcesontlesconteneursquifournissentlesitrateurs
quileursontapproprisafindepermettrelaccsleursdonnes.
Ilnyaquetroismaniresdobtenirunitrateur.Lesitrateursquisonteffectivementdespointeurs
peuventtreobtenusnaturellementenprenantladressedellmentauquelilsdonnentaccs.Les
pointeursnedoiventtreutilissentantquitrateursquepouraccderauxdonnesduntableau,car
lasmantiquedelarithmtiquedespointeurssupposequeleslmentsrfrencssuccessivementpar
unpointeursontstocksendesemplacementscontigusdelammoire.Pourlesitrateursdeconte
206
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
neursenrevanche,ilfautimprativementutiliserdesmthodesspcifiquesduconteneurpourobtenir
desitrateurs.Laplupartdesconteneursfournissentunemthodepourobtenirunitrateurinitial,qui
rfrencelepremierlmentduconteneur,etunemthodepourobtenirlavaleurdelitrateurlorsque
leparcoursduconteneurestachev.Enfin,certainsalgorithmesetcertainesmthodesdesconteneurs
peuventretournerunitrateurlissudeleurtraitement.
Quelle que soit la manire dobtenir les itrateurs, leur validit est soumise des limites.
Premirement, ils deviennent obligatoirement invalides ds lors que le conteneur auquel ils
permettentdaccderestdtruit.Deplus,lesconteneursgrentleurstructurededonnesdemanire
dynamique,etsontsusceptiblesdelarorganiserdsquonlesmanipule.Onveilleradoncneplus
utiliserlesitrateursdunconteneurdsquunemthodepermettantdelemodifierauratappele.
Nepasrespectercettergleconduirait, danslemeilleurdescas, nepasparcourircompltement
lensembledesobjetsduconteneur,etdanslepiredescas,planterimmdiatementleprogramme.
13.4.2.Classificationdesitrateurs
Labibliothquedfinitplusieurscatgoriesditrateursquicontiennentdesitrateursplusoumoins
puissants. Lecomportement desitrateurslespluspuissantsserapprochebeaucoupdespointeurs
classiques, et quasiment touteslesoprationsapplicablesauxpointeurspeuvent ltrecesitra
teurs.Enrevanche,lesitrateursdesclassesplusrestrictivesnedfinissentquunsousensembledes
oprationsquelespointeurssupportent,etnepeuventdonctreutilissquedanslecadredecejeu
doprationsrduit.
Lesalgorithmesdelabibliothquenutilisentquelesitrateursdesclasseslesplusfaiblespermettant
deraliserleurtravail.Ilssimposentcesrestrictionsafindegarantirleurutilisationcorrectemme
aveclesitrateurslesplussimples.Bienentendu,commelespointeursdisposentdetouteslesfonc
tionnalitsdfiniesparlesitrateurs,mmelespluspuissants,lesalgorithmesstandardsfonctionnent
galementavecdespointeurs.Autrementdit,labibliothquestandardestcritedefaonnutiliser
quunepartiedesoprationsapplicablesauxpointeurs,afindegarantirquecequifonctionneavecdes
itrateursfonctionneavecdespointeurs.
Lesitrateursdechaquecatgoriepossdenttouteslespropritsdesitrateursdescatgoriesinf
rieures.Ilexistedoncunehirarchiedanslaclassificationdesitrateurs.Lescatgoriesdfiniespar
labibliothquestandardsontlessuivantes:
lesitrateursdelacatgorieOutputsontutilisspoureffectuerdesaffectationsdevaleursaux
donnesquilsrfrencent.Cesitrateursnepeuventdonctredrfrencsparloprateur*que
danslecadreduneaffectation.IlestimpossibledelirelavaleurdunitrateurdetypeOutput,et
onnedoitcriredanslavaleurquilsrfrencentquunefoisauplus.Lesalgorithmesquiutilisent
cesitrateursdoiventdoncimprativementnefairequuneseulepassesurlesdonnesitres;
lesitrateursdelacatgorieInput
sontsimilairesauxitrateursdetypeOutput,
ceciprs
quilsnepeuventtredrfrencsquepourlireunevaleur.Contrairementauxitrateursdetype
Output, ilestpossibledecomparerdeuxitrateurs. Cependant, lefaitquedeuxitrateurssoient
gauxnesignifieaucunementqueleurssuccesseursleserontencore.Lesalgorithmesquiutilisent
lesitrateursdetypeInputnepeuventdoncfaireaucunehypothsesurlordredeparcoursutilis
parlitrateur.Cesontdoncncessairementdesalgorithmesenunepasse;
lesitrateursdelacatgorieForwardpossdenttouteslesfonctionnalitsdesitrateursdetype
Input et detypeOutput. Commeceuxci, ilsnepeuvent passerquedunevaleurlasuivante,
etjamaisreculerourevenirunevaleurdjitre. Lesalgorithmesquiutilisentdesitrateurs
decettecatgoriesimposentdoncdeneparcourirlesdonnesdesconteneursquedansunseul
sens.Cependant,larestrictionimposesurlgalitdesoprateursdetypeInputestleve,cequi
signifiequeplusieursparcourssuccessifsseferontdanslemmeordre.Lesalgorithmespeuvent
207
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
effectuerplusieursparcours,parexempleencopiantlavaleurinitialedelitrateuretenparcourant
leconteneurplusieursfoisavecchaquecopie;
lesitrateursdelacatgorieBidirectionnaldisposentdetouteslesfonctionnalitsdesitrateurs
detypeForward, maislventlarestrictionsurlesensdeparcours.
Cesitrateurspeuventdonc
revenirsurlesdonnesdjitres,etlesalgorithmesquilesutilisentpeuventdonctravailleren
plusieurspasses,danslesdeuxdirections;
enfin,lesitrateursdelacatgorieRandomAccesssontlespluspuissants.Ilsfournissenttoutes
lesfonctionnalitsdesitrateursdetypeBidirectionnal,pluslapossibilitdaccderauxlments
desconteneursparlintermdiairedunindexenuntempsconstant.Ilnyadoncplusdenotion
desensdeparcours,etlesdonnespeuventtreaccdescommelesdonnesduntableau.Ilest
galement possibledeffectuerlesoprationsclassiquesdelarithmtiquedespointeurssurces
itrateurs.
Touslesitrateursdelabibliothquestandarddriventdelaclassedebasesuivante:
template <classCategory,
classT,classDistance=ptrdiff_t,
classPointer=T*,classReference=T&>
structiterator
{
typedefT
value_type;
typedefDistance difference_type;
typedefPointer
pointer;
typedefReferencereference;
typedefCategory iterator_category;
};
Cetteclasseestdclaredanslentte iterator.
Cetteclassedfinitlestypesdebasedesitrateurs,savoir:letypedesvaleursrfrences,letype
deladiffrenceentredeuxitrateursdanslescalculsdarithmtiquedespointeurs,letypedespoin
teursdesvaleursrfrencesparlitrateur,letypedesrfrencespourcesvaleursetlacatgoriede
litrateur.Cederniertypedoittrelunedesclassessuivantes,galementdfiniesparlabibliothque
standard:
input_iterator_tag,pourlesitrateursdelacatgoriedesitrateursdetypeInput;
output_iterator_tag,pourlesitrateursdelacatgoriedesitrateursdetypeOutput;
forward_iterator_tag,pourlesitrateursdelacatgoriedesitrateursdetypeForward;
bidirectionnal_iterator_tag,pourlesitrateursdelacatgoriedesitrateursbidirectionnels;
random_access_iterator_tag,pourlesitrateursdelacatgoriedesitrateursaccscomplet.
Notezqueletypepardfaut pourladiffrenceentredeuxpointeursest
letypeptrdiff_t, qui est
utilisclassiquement pourlespointeursnormaux. Demme, letypepointeuret letyperfrence
correspondentrespectivement,pardfaut,auxtypesT*etT&.Pourlesitrateurspourlesquelsces
typesnontpasdesens,letypeutilisestvoid,cequipermetdeprovoqueruneerreurdecompilation
sioncherchelesutiliser.
Cestypessontutilissparlesitrateursnativement,cependant,ilsnelesontgnralementpaspar
lesalgorithmes.Eneffet,ceuxcisontsusceptiblesdtreappelesavecdespointeursnormaux,etles
pointeursnedfinissentpastouscestypes.Cestpourcetteraisonquuneclassedetraitsatdfinie
208
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
pourlesitrateursparlabibliothquestandard.Cetteclasseestdclarecommesuitdanslentte
iterator :
template <classIterator>
structiterator_traits
{
typedefIterator::value_type
value_type;
typedefIterator::difference_type difference_type;
typedefIterator::pointer
pointer;
typedefIterator::reference
reference;
typedefIterator::iterator_categoryiterator_category;
};
Laclassedestraitspermetdoncdobtenirdemanireindpendantedelanaturedelitrateurlavaleur
destypesfondamentauxdelitrateur.Commecestypesnexistentpaspourlespointeursclassiques,
cetteclasseestspcialisedelamaniresuivante:
template <classT >
structiterator_traits<T* >
{
typedefT
value_type;
typedefptrdiff_tdifference_type;
typedefT
*pointer;
typedefT
&reference;
typedefrandom_access_iterator_tagiterator_category;
};
Ainsi,letypeiterator_traits<itrateur>::difference_typerenverratoujoursletypepermettantdesto
ckerladiffrenceentredeuxitrateurs,queceuxcisoientdesitrateursoudespointeursnormaux.
Pourcomprendrelimportancedestraitsdesitrateurs,prenonslexemplededeuxfonctionsfournies
parlabibliothquestandardpermettantdavancerunitrateurduncertainnombredtapes,etdecal
culerladiffrenceentredeuxitrateurs.Ilsagitrespectivementdesfonctionsadvance et distance.
Cesfonctionsdevantpouvoirtravailleravecnimportequelitrateur,etnimportequeltypededonne
pourexprimerladiffrenceentredeuxitrateurs,ellesutilisentlaclassedestraits.Ellessontdclares
delamaniresuivantedanslentte iterator :
template <classInputIterator,classDistance
>
voidadvance(InputIterator&i,Distancen);
template <classInputIterator>
iterator_traits<InputIterator>::difference_type
distance(InputIteratorfirst,InputIteratorlast);
209
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
13.4.3.Itrateursadaptateurs
Lesitrateurssontunenotionextrmementutilisedanstoutelabibliothquestandard,
carilsre
groupenttouteslesfonctionnalitspermettantdeffectueruntraitementsquentieldesdonnes.Ce
pendant, ilnexistepastoujoursditrateurpourlessourcesdedonnesquelonmanipule.
Labi
bliothquestandardfournitdonccequelonappelledesitrateursadaptateurs,
quipermettentde
manipulercesstructuresdedonnesenutilisantlanotionditrateurmmesicesstructuresnegrent
pasellesmmeslanotionditrateur.
13.4.3.1.Adaptateurspourlesfluxdentre/sortiestandards
Lesfluxdentre/sortiestandardsdelabibliothquesontnormalementutilissaveclesoprations
>>et <<,respectivementpourrecevoiretpourenvoyerdesdonnes.Ilnexistepasditrateur
detypeInputetdetypeOutputpermettantdelireetdcriresurcesflux.Labibliothquedfinitdonc
desadaptateurspermettantdeconstruirecesitrateurs.
Litrateuradaptateurpourlesfluxdentreestimplmentparlaclasse template istream_iterator.
Cetadaptateurestdclarcommesuitdanslentte iterator :
template <classT,classcharT,classtraits=char_traits
<charT>,
classDistance=ptrdiff_t
>
classistream_iterator:
publiciterator<input_iterator_tag,T,Distance,
constT*,constT& >
{
public:
typedefcharT char_type;
typedeftraitstrait_type;
typedefbasic_istream<char,traits> istream_type;
istream_iterator();
istream_iterator(istream_iterator&flux);
istream_iterator(constistream_iterator
<T,charT,traits,
Distance> &flux);
~istream_iterator();
constT&operator*()const;
constT*operator >()const;
istream_iterator<T,charT,traits,Distance
> &operator++();
istream_iterator<T,charT,traits,Distance
> operator++(int);
};
Lesoprateursdgalitetdingalitsontgalementdfinispourcetitrateur.
Commevouspouvezleconstaterdaprscettedclaration,ilestpossibledeconstruireunitrateur
surunfluxdentrepermettantdelirelesdonnesdecefluxuneune.Silnyaplusdedonnes
liresurceflux,litrateurprendlavaleurdelitrateurdefindefichierpourleflux.Cettevaleurest
cellequiestattribuetoutnouvelitrateurconstruitsansfluxdentre.Lexemplesuivantprsente
commentfairelasommedeplusieursnombreslussurlefluxdentre,etdelafficherlorsquilnya
plusdedonneslire.
Exemple132.Itrateursdefluxdentre
#include <iostream>
#include <iterator>
usingnamespacestd;
210
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
intmain(void)
{
doublesomme=0;
istream_iterator<double,char> is(cin);
while(is!=istream_iterator
<double,char>())
{
somme=somme+*is;
++is;
}
cout << "Lasommedesvaleurslueest:"
<<
somme << endl;
return0;
}
Vouspourrezessayerceprogrammeentapantplusieursnombressuccessivementpuisenenvoyant
uncaractredefindefichieraveclacombinaisondetouches CTRL+Z .Cecaractreprovoquerala
sortiedelaboucle while etafficheralersultat.
Litrateuradaptateurpourlesfluxdesortiefonctionnedemanireencoreplussimple,carilnya
pasfairedetestsurlafindefichier.Ilestdclarcommesuitdanslentteiterator :
template <classT,classcharT=char,classtraits=char_traits<charT>>
classostream_iterator:
publiciterator<output_iterator_tag,void,void,void,void
>
{
public:
typedefcharT char_type;
typedeftraitstrait_type;
typedefbasic_ostream<charT,traits> ostream_type;
ostream_iterator(ostream_type&flux);
ostream_iterator(ostream_type&flux,constcharT*separateur);
ostream_iterator(constostream_iterator
<T,charT,traits> &flux);
~ostream_iterator();
ostream_iterator<T,charT,traits> &operator=(constT&valeur);
ostream_iterator<T,charT,traits> &operator*();
ostream_iterator<T,charT,traits> &operator++();
ostream_iterator<T,charT,traits> &operator++(int);
};
CetitrateurestdetypeOutput,etnepeutdonctredrfrencquedanslebutdefaireunecri
turedanslobjetainsiobtenu.Cedrfrencementretourneenfaitlitrateurluimme,sibienque
lcritureprovoquelappeldeloprateurdaffectationdelitrateur. Cetoprateurenvoiesimple
mentlesdonnessurlefluxdesortiequelitrateurprendenchargeetrenvoiesaproprevaleurafin
deraliserunenouvellecriture.Notezquelesoprateursdincrmentationexistentgalement,mais
nefontstrictementrien.Ilsnesontlquepourpermettredutilisercesitrateurscommedesimples
pointeurs.
Litrateurostream_iteratorpeutenvoyersurlefluxdesortieuntexteintercalaireentrechaquedonne
quonycrit.Cetextepeutservirinsrerdessparateursentrelesdonnes.Cettefonctionnalitpeut
savrertrspratiquepourlcriturededonnesformates.Letexteinsrerautomatiquementdoit
trepassentantquedeuximeargumentduconstructeurdelitrateur.
211
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
Exemple133.Itrateurdefluxdesortie
#include <iostream>
#include <iterator>
usingnamespacestd;
constchar*texte[6]={
"Bonjour","tout","le","monde","!",NULL
};
intmain(void)
{
ostream_iterator<constchar*,char> os(cout,"");
inti=0;
while(texte[i]!=NULL)
{
*os=texte[i]; //Ledrfrencementestfacultatif.
++os;
//Cetteligneestfacultative.
++i;
}
cout << endl;
return0;
}
Ilexistegalementdesadaptateurspourlestamponsdefluxdentre/sortiebasic_streambuf.
Le
premieradaptateurestimplmentparlaclasse template istreambuf_iterator.Ilpermetdelireles
donnesprovenantduntampondefluxbasic_streambufaussisimplementquenmanipulantunpoin
teuretenlisantlavaleurdelobjetpoint.Ledeuximeadaptateur,ostreambuf_iterator,permetquant
luidcriredansuntamponenaffectantunenouvellevaleurlobjetrfrencparlitrateur.Ces
adaptateursfonctionnentdoncexactementdelammemanirequelesitrateurspourlesfluxdentre
/sortieformats.Enparticulier,lavaleurdefindefichierqueprendlitrateurdentrepeuttrer
cuprelaideduconstructeurpardfautdelaclasseistreambuf_iterator,instanciepourletypede
tamponutilis.
Note:Loprateurdedincrmentationsuffixdesitrateursistreambuf_iteratorauntypede
retourparticulierqui permetdereprsenterlavaleurprcdentedelitrateuravant incrmen
tation.Lesobjetsdecetypesonttoujoursdrfrenableslaidedeloprateur *.Laraison
decetteparticularitestquelecontenudutamponpeuttremodifiaprslappeldeloprateur
operator++(int) ,maislanciennevaleurdecetitrateurdoittoujourspermettredaccder
lobjetquilrfrenait.Lavaleurretourneparlitrateurcontientdoncunesauvegardedecetob
jetetpeutsevoirappliquerloprateurdedrfrencement* parlappelantafindenrcuprer
lavaleur.
LanotiondetampondefluxseraprsenteendtaildanslaSection15.2.
13.4.3.2.Adaptateurspourlinsertiondlmentsdanslesconteneurs
Lesitrateursfournisparlesconteneurspermettentdenparcourirlecontenuetdobtenirunerf
rencesurchacundeleurslments.Cecomportementesttoutfaitclassiqueetconstituemmeune
desbasesdelanotionditrateur.Toutefois,linsertiondenouveauxlmentsdansunconteneurne
peutsefairequeparlintermdiairedesmthodesspcifiquesauxconteneurs.Labibliothquestan
dardC++dfinitdoncdesadaptateurspourdesitrateursditsdinsertion, quipermettentdinsrer
212
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
deslmentsdansdesconteneursparunsimpledrfrencementetunecriture.Grcecesadapta
teurs,linsertiondeslmentsdanslesconteneurspeuttreralisedemanireuniforme,delamme
manirequoncriraitdansuntableauquiseredimensionneraitautomatiquement,chaquecriture.
Ilestpossibledinsrerlesnouveauxlmentsenplusieursendroitsdanslesconteneurs.Ainsi,les
lmentspeuventtreplacsaudbutduconteneur,safin,ouaprsunlmentdonn.Bienentendu,
cesnotionsnont desensquepourlesconteneursqui nesont pasordonns, puisquedanslecas
contraire,lapositiondellmentinsrestdtermineparleconteneurluimme.
Laclasse template back_insert_iteratorestlaclassedeladaptateurdinsertionenfindeconteneur.
Elleestdclarecommesuitdanslentte iterator :
template <classContainer>
classback_insert_iterator:
publiciterator<output_iterator_tag,void,void,void,void
>
{
public:
typedefContainercontainer_type;
explicitback_insert_iterator(Container&conteneur);
back_insert_iterator<Container> &
operator=(consttypenameContainer::value_type&valeur);
back_insert_iterator<Container> &operator*();
back_insert_iterator<Container> &operator++();
back_insert_iterator<Container> operator++(int);
};
Commevouspouvezleconstater, lesobjetsdesinstancescetteclassepeuventtreutilisscomme
desitrateursdetypeOutput. Loprateurdedrfrencement *renvoielitrateurluimme, si
bienquelesaffectationssurlesitrateursdrfrencssonttraitesparloprateur operator=de
litrateurluimme. Cestdonccetoprateurquiajoutellmentaffecterlafinduconteneur
auquellitrateurpermetdaccder,enutilisantlamthode push_back decedernier.
Demme,laclasse template front_insert_iteratordeladaptateurdinsertionenttedeconteneur
estdclarecommesuitdanslentte iterator :
template <classContainer>
classfront_insert_iterator:
publiciterator<output_iterator_tag,void,void,void,void
>
{
public:
typedefContainercontainer_type;
explicitfront_insert_iterator(Container&conteneur);
front_insert_iterator<Container> &
operator=(consttypenameContainer::value_type&valeur);
front_insert_iterator<Container> &operator*();
front_insert_iterator<Container> &operator++();
front_insert_iterator<Container> operator++(int);
};
Sonfonctionnementestidentiqueceluideback_insert_iterator,ceciprsquileffectuelesinser
tionsdeslmentsaudbutduconteneur,parlintermdiairedesamthodepush_front.
Enfin,laclasse template deladaptateurditrateurdinsertionunepositiondonneestdclare
commesuit:
template <classContainer>
classinsert_iterator:
publiciterator<output_iterator_tag,void,void,void,void
>
213
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
{
public:
typedefContainercontainer_type;
insert_iterator(Container&conteneur,
typenameContainer::iteratorposition);
insert_iterator<Container> &
operator=(consttypenameContainer::value_type&valeur);
insert_iterator<Container> &operator*();
insert_iterator<Container> &operator++();
insert_iterator<Container> operator++(int);
};
Leconstructeur decetteclasseprendenparamtre,
enplusduconteneur sur lequel litrateur
dinsertiondoit travailler, unitrateur spcifiant lapositionlaquelleleslmentsdoivent
tre
insrs.Leslmentssontinsrsjusteavantllmentrfrencparlitrateurfournienparamtre.
Deplus,ilssontinsrssquentiellement,lesunsaprslesautres,dansleurordredaffectationvia
litrateur.
LabibliothquestandardC++fournit troisfonctions template qui permettent dobtenirlestrois
typesditrateurdinsertionpourchaqueconteneur. Cesfonctionssontdclarescommesuitdans
lentte iterator :
template <classContainer>
back_insert_iterator<Container>
back_inserter(Container&conteneur);
template <classContainer>
front_insert_iterator<Container>
front_inserter(Container&conteneur);
template <classContainer,classIterator>
insert_iterator<Container>
inserter(Container&conteneur,Iteratorposition);
Leprogrammesuivantutiliseunitrateurdinsertionpourremplirunelistedlment,
afficherlecontenu.
avantden
Exemple134.Itrateurdinsertion
#include <iostream>
#include <list>
#include <iterator>
usingnamespacestd;
//Dfinitletypelistedentier:
typedeflist<int> li_t;
intmain()
{
//Creuneliste:
li_tlst;
//Insredeuxlmentsdanslalistedelamanireclassique:
lst.push_back(1);
lst.push_back(10);
214
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
//Rcupreunitrateurrfrenantlepremierlment:
li_t::iteratorit=lst.begin();
//Passeaudeuximelment:
++it;
//Construitunitrateurdinsertionpourinsrerdenouveaux
//lmentsavantledeuximelmentdelaliste:
insert_iterator<li_t> ins_it=inserter(lst,it);
//Insreleslmentsaveccetitrateur:
for(inti=2;i
< 10;++i)
{
*ins_it=i;
++ins_it;
}
//Affichelecontenudelaliste:
it=lst.begin();
while(it!=lst.end())
{
cout << *it << endl;
++it;
}
return0;
}
LamaniredutiliserleconteneurdetypelistseradcriteendtaildansleChapitre17.
13.4.3.3.Itrateurinversepourlesitrateursbidirectionnels
Lesitrateursbidirectionnelsetlesitrateursaccsalatoirepeuventtreparcourusdanslesdeux
sens.Pourcesitrateurs,ilestdoncpossiblededfinirunitrateurassocidontlesensdeparcours
estinvers.Lepremierlmentdecetitrateurestdoncledernierlmentdelitrateurassoci,et
inversement.
LabibliothquestandardC++dfinitunadaptateurpermettantdobtenirunitrateurinversefacile
mentdanslentte iterator.Ilsagitdelaclasse template reverse_iterator:
template <classIterator>
classreverse_iterator:
publiciterator<
iterator_traits<Iterator>::iterator_category,
iterator_traits<Iterator>::value_type,
iterator_traits<Iterator>::difference_type,
iterator_traits<Iterator>::pointer,
iterator_traits<Iterator>::reference>
{
public:
typedefIteratoriterator_type;
reverse_iterator();
explicitreverse_iterator(Iteratoriterateur);
Iteratorbase()const;
Referenceoperator*()const;
Pointeroperator>()const;
reverse_iterator&operator++();
reverse_iteratoroperator++(int);
reverse_iterator&operator();
reverse_iteratoroperator(int);
reverse_iteratoroperator+(Distancedelta)const;
215
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
reverse_iterator&operator+=(Distancedelta);
reverse_iteratoroperator(Distancedelta)const;
reverse_iterator&operator=(Distancedelta);
Referenceoperator[](Distancedelta)const;
};
216
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
//Remplitlaliste:
for(inti=0;i
< 10;++i)
li.push_back(i);
//Affichelecontenudelalistelenvers:
li_t::reverse_iteratorrev_it=li.rbegin();
while(rev_it!=li.rend())
{
cout << *rev_it << endl;
++rev_it;
}
return0;
}
13.5.Abstractiondesfonctions:lesfoncteurs
Laplupart desalgorithmesdelabibliothquestandard, ainsi quequelquesmthodesdesclasses
quellefournit, donnentlapossibilitlutilisateurdappliquerunefonctionauxdonnesmanipu
les.Cesfonctionspeuventtreutilisespourdiffrentestches,commepourcomparerdeuxobjets
parexemple,outoutsimplementpourenmodifierlavaleur.
Cependant, labibliothquestandardnutilisepascesfonctionsdirectement, maisaplutt recours
uneabstractiondesfonctions: lesfoncteurs. Unfoncteurnest riendautrequunobjet dont la
classedfinitloprateurfonctionnel ().Lesfoncteursontlaparticularitdepouvoirtreutiliss
exactementcommedesfonctionspuisquilestpossibledeleurappliquerleuroprateurfonctionnel
selonunecrituresimilaireunappeldefonction.Cependant,ilssontunpeupluspuissantsquede
simplesfonctions,carilspermettentdetransporter,enplusducodedeloprateurfonctionnel,des
paramtresadditionnelsdansleursdonnesmembres.Lesfoncteursconstituentdoncunefonctionna
litextrmementpuissantequipeuttretrspratiqueendenombreuxendroits.Enfait,commeonle
verraplusloin,toutefonctionpeuttretransformeenfoncteur.Lesalgorithmesdelabibliothque
standardpeuventdoncgalementtreutilissavecdesfonctionsclassiquesmoyennantcettepetite
transformation.
Lesalgorithmesdelabibliothquestandardquiutilisentdesfoncteurssontdclarsavecunparamtre
template dontlavaleurseracelledufoncteurpermettantderaliserloprationappliquersurles
donnesencoursdetraitement. Auseindecesalgorithmes, lesfoncteurssont utilisscommede
simplesfonctions, et labibliothquestandardnefait doncpasdautrehypothsesurleurnature.
Cependant, il est ncessairedenedonnerquedesfoncteursenparamtresauxalgorithmesdela
bibliothquestandard,pasdesfonctions.Cestpourcetteraisonquelabibliothquestandarddfinit
uncertainnombredefoncteursstandardsafindefaciliterlatcheduprogrammeur.
13.5.1.Foncteursprdfinis
Labibliothquenutilise, danssesalgorithmes, quedesfoncteursqui neprennent quunoudeux
paramtres. Lesfoncteursquiprennentunparamtreetunseulsontditsunaires, alorsqueles
foncteursquiprennentdeuxparamtressontqualifisdebinaires.Afindefaciliterlacrationde
foncteursutilisablesavecsesalgorithmes,labibliothquestandarddfinitdeuxclassesdebasequi
pourlesfoncteursunairesetbinaires.Cesclassesdebasesontlessuivantes:
template <classArg,classResult>
structunary_function
217
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
{
typedefArg
argument_type;
typedefResultresult_type;
};
template <classArg1,classArg2,classResult>
structbinary_function
{
typedefArg1
first_argument_type;
typedefArg2
second_argument_type;
typedefResultresult_type;
};
Cesclassessontdfiniesdanslentte functional.
Labibliothquedfinitgalementuncertainnombredefoncteursstandardsquiencapsulentlesop
rateursdulangagedanscetentte.Cesfoncteurssontlessuivants:
template <classT >
structplus:binary_function
<T,T,T >
{
Toperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structminus:binary_function
<T,T,T >
{
Toperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structmultiplies:binary_function
<T,T,T >
{
Toperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structdivides:binary_function
<T,T,T >
{
Toperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structmodulus:binary_function
<T,T,T >
{
Toperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structnegate:unary_function
<T,T >
{
Toperator()(constT&operande)const;
};
template <classT >
structequal_to:binary_function
<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
218
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
};
template <classT >
structnot_equal_to:binary_function<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structgreater:binary_function
<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structless:binary_function
<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structgreater_equal:binary_function <T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
};
template <classT >
structless_equal:binary_function
<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
};
Cesfoncteurspermettentdutiliserlesprincipauxoprateursdulangagecommedesfonctionsclas
siquesdanslesalgorithmesdelabibliothquestandard.
Exemple136.Utilisationdesfoncteursprdfinis
#include <iostream>
#include <functional>
usingnamespacestd;
//Fonctiontemplateprenantenparamtredeuxvaleurs
//etunfoncteur:
template <classT,classF >
Tapplique(Ti,Tj,Ffoncteur)
{
//Appliqueloprateurfonctionnelaufoncteur
//aveccommeargumentslesdeuxpremiersparamtres:
returnfoncteur(i,j);
}
intmain(void)
{
//Construitlefoncteurdesomme:
plus<int> foncteur_plus;
//Utilisecefoncteurpourfairefaireuneaddition
219
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
//lafonction"applique":
cout << applique(2,3,foncteur_plus)<< endl;
return0;
}
Danslexempleprcdent,lafonction templateappliqueprendentroisimeparamtreunfonc
teuret lutilisepourraliserloprationfaireaveclesdeuxpremiersparamtres. Cettefonction
nepeutthoriquementtreutilisequavecdesobjetsdisposantdunoprateurfonctionnel (),et
pasavecdesfonctionsnormales.Labibliothquestandardfournitdonclesadaptateurssuivants,qui
permettentdeconvertirrespectivementnimportequellefonctionunaireoubinaireenfoncteur:
template <classArg,classResult>
classpointer_to_unary_function:
publicunary_function<Arg,Result>
{
public:
explicitpointer_to_unary_function(Result(*fonction)(Arg));
Resultoperator()(Argargument1)const;
};
template <classArg1,Arg2,Result>
classpointer_to_binary_function:
publicbinary_function<Arg1,Arg2,Result>
{
public:
explicitpointer_to_binary_function(Result(*fonction)(Arg1,Arg2));
Resultoperator()(Arg1argument1,Arg2argument2)const;
};
template <classArg,classResult>
pointer_to_unary_function
<Arg,Result>
ptr_fun(Result(*fonction)(Arg));
template <classArg,classResult>
pointer_to_binary_function
<Arg1,Arg2,Result>
ptr_fun(Result(*fonction)(Arg1,Arg2));
Lesdeuxsurchargesdelafonction templateptr_funpermettentdefaciliterlaconstructiondun
foncteurunaireoubinairepartirdupointeurdunefonctiondummetype.
Exemple137.Adaptateursdefonctions
#include <iostream>
#include <functional>
usingnamespacestd;
template <classT,classF >
Tapplique(Ti,Tj,Ffoncteur)
{
returnfoncteur(i,j);
}
//Fonctionclassiqueeffectuantunemultiplication:
intmul(inti,intj)
{
returni*j;
220
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
}
intmain(void)
{
//Utiliseunadaptateurpourtransformerlepointeur
//surlafonctionmulenfoncteur:
cout << applique(2,3,ptr_fun(&mul))<< endl;
return0;
}
Note:EnralitlelangageC++estcapabledappelerunefonctiondirectementpartirdeson
adresse,sansdrfrencement.Depluslenomdunefonctionreprsentetoujourssontadresse,
etestdoncconvertiimplicitementparlecompilateurenpointeurdefonction.Parconsquent,il
esttoutfaitpossibledutiliserlafonction templateapplique avecuneautrefonctiondeux
paramtres,commedanslappelsuivant:
applique(2,3,mul);
Cependant,cettecritureprovoquelaconversionimplicitedelidentificateurmul enpointeurde
fonctionprenantdeuxentiersenparamtresetrenvoyantunentier,dunepart,etlappel dela
template
fonction mul parlintermdiairedesonpointeursansdrfrencementdanslafonction
applique dautrepart.Cettecritureestdoncaccepteparlecompilateurpartolrance,mais
nestpasrigoureusementexacte.
LabibliothquestandardC++dfinitgalementdesadaptateurspourlespointeursdemthodesnon
statiquesdeclasses. Cesadaptateursseconstruisent commelesadaptateursdefonctionsstatiques
classiques,ceciprsqueleurconstructeurprendunpointeurdemthodedeclasseetnonunpointeur
defonctionnormale.Ilssontdclarsdelamaniresuivantedanslenttefunctional :
template <classResult,classClass
>
classmem_fun_t:
publicunary_function<Class*,Result>
{
public:
explicitmem_fun_t(Result(Class::*methode)());
Resultoperator()(Class*pObjet);
};
template <classResult,classClass,classArg
>
classmem_fun1_t:
publicbinary_function<Class*,Arg,Result>
{
public:
explicitmem_fun1_t(Result(Class::*methode)(Arg));
Resultoperator()(Class*pObjet,Argargument);
};
template <classResult,classClass
>
classmem_fun_ref_t:
publicunary_function<Class,Result>
{
public:
explicitmem_fun_ref_t(Result(Class::*methode)());
221
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
Resultoperator()(Class&objet);
};
template <classResult,classClass,classArg
>
classmem_fun1_ref_t:
publicbinary_function<Class,Arg,Result>
{
public:
explicitmem_fun1_ref_t(Result(Class::*methode)(Arg));
Resultoperator()(Class&objet,Argargument);
};
template <classResult,classClass
>
mem_fun_t<Result,Class> mem_fun(Result(Class::*methode)());
template <classResult,classClass,classArg
>
mem_fun1_t<Result,Class> mem_fun(Result(Class::*methode)(Arg));
template <classResult,classClass
>
mem_fun_ref_t<Result,Class> mem_fun_ref(Result(Class::*methode)());
template <classResult,classClass,classArg
>
mem_fun1_ref_t<Result,Class>
mem_fun_ref(Result(Class::*methode)(Arg));
Commevouspouvezleconstaterdaprsleursdclarationslesoprateursfonctionnelsdecesadap
tateursprennentenpremierparamtresoitunpointeursurlobjetsurlequellefoncteurdoittravailler
(adaptateursmem_fun_tetmem_fun1_t),soitunerfrencesurcetobjet(adaptateursmem_fun_ref_t
etmem_fun1_ref_t).Lepremierparamtredecesfoncteursestdoncrservpourlobjetsurlequel
lamthodeencapsuledoittreappele.
Enfait,lalistedesadaptateursprsentecidessusnestpasexhaustive.Eneffet,chaqueadaptateur
prsentestdoubldunautreadaptateur,capabledeconvertirlesfonctionsmembres const.Ilexiste
donchuitadaptateursautotalpermettantdeconstruiredesfoncteurspartirdesfonctionsmembres
declasses.Pourdiminuercettecomplexit,labibliothquestandarddfinitplusieurssurchargespour
lesfonctions mem_fun et mem_fun_ref,quipermettentdeconstruiretouscesfoncteursplusfacile
ment,sansavoirsesoucierdelanaturedespointeursdefonctionmembreutiliss.Ilestfortement
recommanddelesutiliserpluttquedechercherconstruirecesobjetsmanuellement.
13.5.2.Prdicatsetfoncteursdoprateurslogiques
Lesfoncteursquipeuventtreutilissdansuneexpressionlogiqueconstituentuneclasseparticulire:
lesprdicats.Unprdicatestunfoncteurdontloprateurfonctionnelrenvoieunboolen.Lesprdi
catsontdoncunsenslogique,etcaractrisentunepropritquinepeuttrequevraieoufausse.
Labibliothquestandardfournit desprdicatsprdfinisqui effectuent lesoprationslogiques
desoprateurslogiquesdebasedulangage. Cesprdicatssont galement dclarsdanslentte
functional :
template <classT >
structlogical_and:
binary_function<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
222
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
};
template <classT >
structlogical_or:
binary_function<T,T,bool>
{
booloperator()(constT&operande1,constT&operande2)const;
};
Cesfoncteursfonctionnentexactementcommelesfoncteursvusdanslasectionprcdente.
Labibliothquestandarddfinitaussideuxfoncteursparticuliers,quipermettentdeffectuerlanga
tiondunautreprdicat.Cesdeuxfoncteurstravaillentrespectivementsurlesprdicatsunairesetsur
lesprdicatsbinaires:
template <classPredicate>
classunary_negate:
publicunary_function<typenamePredicate::argument_type,bool
>
{
public:
explicitunary_negate(constPredicate&predicat);
booloperator()(constargument_type&argument)const;
};
template <classPredicate>
classbinary_negate:
publicbinary_function<typenamePredicate::first_argument_type,
typenamePredicate::second_argument_type,bool
>
{
public:
explicitbinary_negate(constPredicate&predicat);
booloperator()(constfirst_argument_type&argument1,
constsecond_argument_type&argument2)const;
};
template <classPredicate>
unary_negate<Predicate> not1(constPredicate&predicat);
template <classPredicate>
binary_negate<Predicate> not2(constPredicate&predicat);
13.5.3.Foncteursrducteurs
Nousavonsvuquelabibliothquestandardnetravaillaitquavecdesfoncteursprenantauplusdeux
arguments. Certainsalgorithmesnutilisantquedesfoncteursunaires, ilsnesontnormalementpas
capablesdetravailleraveclesfoncteursbinaires.Toutefois,siundesparamtresdunfoncteurbinaire
estfixunevaleurdonne,celuicidevientunaire,puisqueseulledeuximeparamtrepeutvarier.
Ilestdoncpossibledutiliserdesfoncteursbinairesmmeavecdesalgorithmesquinutilisentque
desfoncteursunaires,laconditiondefixerlundesparamtres.
Labibliothquestandarddfinitdesfoncteursspciauxquipermettentdetransformertoutfoncteur
binaireenfoncteurunairepartirdelavaleurdelundesparamtres.Cesfoncteurseffectuentune
oprationditederductioncarilsrduisentlenombredeparamtresdufoncteurbinaireun.Pour
223
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
cela,ilsdfinissentunoprateurfonctionnelunargument,quiappliqueloprateurfonctionneldu
foncteurbinairecetargumentetunevaleurfixequilsmmorisentendonnemembre.
Cesfoncteursrducteurssontdclars,commelesautresfoncteurs,danslentte fonctional :
template <classOperation>
classbinder1st:
publicunary_function<typenameOperation::second_argument_type,
typenameOperation::result_type
>
{
protected:
Operationop;
typenameOperation::first_argument_typevalue;
public:
binder1st(constOperation&foncteur,
consttypenameOperation::first_argument_type&valeur);
result_typeoperator()(constargument_type&variable)const;
};
template <classOperation>
classbinder2nd:
publicunary_function<typenameOperation::first_argument_type,
typenameOperation::result_type
>
{
protected:
Operationop;
typenameOperation::second_argument_typevalue;
public:
binder2nd(constOperation&foncteur,
consttypenameOperation::second_argument_type&valeur);
result_typeoperator()(constargument_type&variable)const;
};
template <classOperation,classT >
binder1st<Operation> bind1st(constOperation&foncteur,constT&valeur);
template <classOperation,classT >
binder2nd<Operation> bind2nd(constOperation&foncteur,constT&valeur);
Ilexistedeuxjeuxderducteurs, quipermettentderduirelesfoncteursbinairesenfixantrespec
tivementleurpremierouleurdeuximeparamtre. Lesrducteursquifigentlepremierparamtre
peuventtreconstruitslaidedelafonction templatebind1st, etceuxquifigentlavaleurdu
deuximeparamtrepeuventltrelaidedelafonction bind2nd.
Exemple138.Rductiondefoncteursbinaires
#include <iostream>
#include <functional>
usingnamespacestd;
//Fonctiontemplatepermettantdappliquerunevaleur
//unfoncteurunaire.Cettefonctionnepeutpas
//treutiliseavecunfoncteurbinaire.
template <classFoncteur>
typenameFoncteur::result_typeapplique(
224
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
Foncteurf,
typenameFoncteur::argument_typevaleur)
{
returnf(valeur);
}
intmain(void)
{
//Construitunfoncteurbinairedadditiondentiers:
plus<int> plus_binaire;
inti;
for(i=0;i < 10;++i)
{
//Rduitlefoncteurplus_binaireenfixantson
//premierparamtre35.Lefoncteurunaireobtenu
//estensuiteutilisaveclafonctionapplique:
cout << applique(bind1st(plus_binaire,35),i)<< endl;
}
return0;
}
13.6.Gestionpersonnalisedelammoire:les
allocateurs
Lunedesplusgrandesforcesdelabibliothquestandardestdedonnerauxprogrammeurslecontrle
totaldelagestiondelammoirepourleursobjets. Eneffet, lesconteneurspeuventtreamens
crerungrandnombredobjets,dontlecomportementpeuttretrsdiffrentselonleurtype.Si,dans
lamajoritdescas,lagestiondelammoireeffectueparlabibliothquestandardconvient,ilpeut
parfoistrencessairedeprendreenchargesoimmelesallocationsetleslibrationsdelammoire
pourcertainsobjets.
Labibliothquestandardutilisepourcelalanotiondallocateur. UnallocateurestuneclasseC++
disposantdemthodesstandardsquelesalgorithmesdelabibliothquepeuventappelerlorsquelles
dsirentalloueroulibrerdelammoire.Pourcela,lesconteneursdelabibliothquestandardC++
prennenttousunparamtre template reprsentantletypedesallocateursmmoirequilsdevront
utiliser. Bienentendu, labibliothquestandardfournit unallocateur par dfaut, et ceparamtre
template prendpardfautlavaleurdecetallocateur.
Ainsi, lesprogrammesquinedsirentpas
spcifierunallocateurspcifiquepourrontsimplementignorerceparamtretemplate.
Lesautresprogrammespourrontdfinirleurpropreallocateur.Cetallocateurdevravidemmentfour
nirtouteslesfonctionnalitsdelallocateurstandard, et satisfairequelquescontraintesparticu
lires.Linterfacedesallocateursestfournieparladclarationdelallocateurstandard,danslentte
memory :
template <classT >
classallocator
{
public:
typedefsize_t
size_type;
typedefptrdiff_tdifference_type;
typedefT
*pointer;
typedefconstT
*const_pointer;
225
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
typedefT
&reference;
typedefconstT
&const_reference;
typedefT
value_type;
template <classU >
structrebind
{
typedefallocator<U> other;
};
allocator()throw();
allocator(constallocator&)throw();
template <classU >
allocator(constallocator
<U> &)throw();
~allocator()throw();
pointeraddress(referenceobjet);
const_pointeraddress(const_referenceobjet)const;
pointerallocate(size_typenombre,
typenameallocator<void>::const_pointerindice);
voiddeallocate(pointeradresse,size_typenombre);
size_typemax_size()constthrow();
voidconstruct(pointeradresse,constT&valeur);
voiddestroy(pointeradresse);
};
//Spcialisationpourletypevoidpourliminerlesrfrences:
template <>
classallocator<void>
{
public:
typedefvoid
*pointer;
typedefconstvoid*const_pointer;
typedefvoid
value_type;
template <classU >
structrebind
{
typedefallocator<U> other;
};
};
Vousnoterezquecetallocateurestspcialispourletypevoid,
typedef nontpasdesenspourcetypededonne.
carcertainesmthodesetcertains
Lerledechacunedesmthodesdesallocateursesttrsclairetnappellepasbeaucoupdecommen
taires.Lesdeuxsurchargesdelamthode address permettentdobtenirladressedunobjetallou
parcetallocateurpartirdunerfrence.Lesmthodes allocate et deallocate permettentres
pectivementderaliseruneallocationdemmoireetlalibrationdubloccorrespondant.Lamthode
allocate prendenparamtrelenombredobjetsquidevronttrestocksdansleblocalloueret
unpointeurfournissantdesinformationspermettantdedterminerlemplacementolallocationdoit
sefairedeprfrence.Cedernierparamtrepeutnepastreprisencompteparlimplmentationde
labibliothquestandardquevousutilisezet,sillest,sonrlenestpasspcifi.Danstouslescas,
silnestpasnul,cepointeurdoittreunpointeursurunblocdjallouparcetallocateuretnon
encorelibr.Laplupartdesimplmentationschercherontallouerunblocadjacentceluifourni
enparamtre,maiscenestpastoujourslecas.Demme,notezquelenombredobjetsspcifila
mthode deallocate doitexactementtrelemmequeceluiutilispourlallocationdanslappel
correspondant allocate.Autrementdit,lallocateurnemmorisepasluimmelatailledesblocs
mmoirequilafourni.
226
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
allocate nest ni libr, ni rallou, ni
Note:Lepointeurpassenparamtrelamthode
rutilisparlallocateur.Ilnesagitdoncpasdunemodificationdelataillemmoiredublocfourni
enparamtre, et ceblocdevratoujourstrelibrindpendamment decelui qui seraallou.
Cepointeurnestutilisparlesimplmentationsquecommeunindicefourni lallocateurafin
doptimiserlesallocationsdeblocsdanslesalgorithmesetlesconteneursinternes.
Exemple139.Utilisationdelallocateurstandard
#include <iostream>
#include <memory>
usingnamespacestd;
classA
{
public:
A();
A(constA&);
~A();
};
A::A()
{
cout << "ConstructeurdeA" << endl;
}
A::A(constA&)
{
cout << "ConstructeurdecopiedeA" << endl;
}
A::~A()
{
cout << "DestructeurdeA"
}
<< endl;
intmain(void)
227
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
{
//ConstruituneinstancedelallocateurstandardpourlaclasseA:
allocator<A> A_alloc;
//AllouelespacencessairepourstockercinqinstancesdeA:
allocator<A>::pointerp=A_alloc.allocate(5);
//Construitcesinstancesetlesinitialise:
Ainit;
inti;
for(i=0;i <5;++i)
A_alloc.construct(p+i,init);
//Dtruitcesinstances:
for(i=0;i <5;++i)
A_alloc.destroy(p+i);
//Reconstruitces5instances:
for(i=0;i <5;++i)
A_alloc.construct(p+i,init);
//Destructionfinale:
for(i=0;i <5;++i)
A_alloc.destroy(p+i);
//Librelammoire:
A_alloc.deallocate(p,5);
return0;
}
Vousvoyezicilintrtquepeutavoirlesallocateursdelabibliothquestandard.
Lesalgorithmes
peuventcontrlerexplicitementlaconstructionetladestructiondesobjets,
etsurtoutlesdissocier
desoprationsdallocationet delibrationdelammoire. Ainsi, unalgorithmedevant effectuer
beaucoupdallocationsmmoirepourra,silledsire,effectuercesallocationsunebonnefoispour
toutesgrcelallocateurstandard,etneffectuerlesoprationsdeconstructionetdedestructiondes
objetsquelorsquecelaestncessaire.Enprocdantainsi,letempspassdanslesroutinesdegestion
delammoireestliminetlalgorithmeestdautantplusperformant. Inversement, unutilisateur
exprimentpourradfinirsonpropreallocateurmmoireadaptauxobjetsquil
voudrastocker
dansunconteneur. Enimposant auconteneurdelabibliothquestandarddutilisercet
allocateur
personnalis,ilobtiendradesperformancesoptimales.
Ladfinitiondunallocateurmaisonconsistesimplementimplmenteruneclasse template dispo
santdesmmesmthodesettypesqueceuxdfinisparlallocateurallocator.Toutefois,ilfautsavoir
quelabibliothqueimposedescontraintessurlasmantiquedecesmthodes:
228
touteslesinstancesdunallocateurduntypedonnpermettentgalementdaccderlamme
mmoire.Celasignifiequilnestpasncessairededisposerduneinstanceglobalepourchaque
allocateur,ilsuffitsimplementdecrerunobjetlocaldunedesinstancesdelaclasse template
delallocateurpouralloueret librerdelammoire. Notezici ladiffrenceaveclacontrainte
template instancies,
prcdente:cettecontrainteporteicisurlesobjetsinstancesdesclasses
alorsquelacontrainteprcdenteportaitsurlesinstancesellesmmesdelaclasse template de
lallocateur;
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
touteslesmthodesdelallocateurdoiventsexcuterdansuntempsamorticonstant(celasignifie
queletempsdexcutiondecesmthodesestmajorparunebornesuprieurefixe,quinedpend
pasdunombredallocationdjeffectuesnidelatailledublocdemmoiredemand);
Pourterminercetourdhorizondesallocateurs,sachezquelabibliothquestandarddfinitgalement
untypeitrateurspcialpermettantdestockerdesobjetsdansunezonedemmoirenoninitialise.
Cet itrateur, nommraw_storage_iterator, est detypeOutput et nest utilisqueninterneparla
bibliothquestandard.Demme,labibliothquedfinitdesalgorithmespermettantdeffectuerdes
copiesbrutesdeblocsmmoireetdautresmanipulationssurlesblocsallousparlesallocateurs.Ces
algorithmessontgalementutilisseninterne,etneserontdoncpasdcritsplusendtailici.
13.7.Notiondecomplexitalgorithmique
EnaucunendroitlanormeC++nespcifielamanirederaliserunefonctionnalit. Eneffet, elle
nimposenilesstructuresdedonnes,nilesalgorithmesutiliser.Lesseuleschosesquisontsp
cifiesparlanormesontlesinterfacesbienentendu(cestdirelesnomsdesclasses,desobjetset
lessignaturesdesfonctionsetdesmthodes)etlasmantiquedesdiversesoprationsralisables.Ce
pendant,lanormeC++nepermetpasderalisertoutescesfonctionnalitsnimportecomment,car
elleimposegalementdescontraintesdeperformancessurlaplupartdesesalgorithmesainsiquesur
lesmthodesdesconteneurs.Cescontraintessontexprimesgnralemententermedecomplexit
algorithmique,aussiestilncessairedeprciserunpeucettenotion.
Note:Enpratique,lescontraintesdecomplexitimposesparlabibliothquestandardsonttout
simplementlesplusfortesralisables.Endautrestermes,onnepeutpasfairemieuxqueles
algorithmesdelabibliothquestandard.
13.7.1.Gnralits
Lanaturedeschosesveutqueplusunprogrammeadedonnestraiter,plusilprenddutempspour
lefaire. Cependant, certainsalgorithmessecomportentmieuxquedautreslorsquelenombredes
donnestraiteraugmente. Parexemple, unalgorithmemalcritpeutvoirsontempsdexcution
crotreexponentiellementaveclaquantitdedonnestraiter, alorsquunalgorithmebientudi
auraitnauraittpluslentqueproportionnellementcemmenombre.Enpratique,celasignifieque
cetalgorithmeesttoutsimplementinutilisablelorsquelenombrededonnesaugmente.Parexemple,
lefaitdedoublerlatailledelensembledesdonnestraiterpeutengendreruntempsdecalculquatre
foispluslong,alorsqueletempsdexcutiondelalgorithmebiencritnauraittquedudouble
seulement.Etsilenombrededonnesesttripletnondoubl,cetalgorithmedemanderahuitfoisplus
detemps,loletripleseulementestncessaire.Silonprendquatrefoisplusdedonnes,letemps
229
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
seramultipliparsoixantequatre. Onvoit clairement queleschosesnevont pasensamliorant
quandlenombrededonnestraiteraugmente...
Enralit,ilestrelativementraredeconsidrerletempsdexcutionpourqualifierlesperformances
dunalgorithme.Eneffet,lecalculdutempsdexcutionnestpastoujourspossibledunepart,parce
quilsebasesurdesparamtresaprioriinconnus,etnestpastoujourscequiestintressantauni
veauducotdautrepart.Pourillustrercedernierpoint,supposonsquechaqueoprationeffectue
parlalgorithmecoteunecertainequantitdnergie.Danscertainscontextes,ilestplusimportant
desintresserlnergiedpensequautempspasspoureffectuerlensembledestraitements.Or
certainesoprationspeuventprendrerelativementpeudetemps,maiscotertrschernergtique
mentparlant,etloptimisationdutempsdexcutionnedonnepasforcmentlameilleuresolution.
Unautreexempleesttoutsimplementceluidelalecturedesecteurssurundisquedur.Lalecturede
cessecteursensoineprendpastellementdetemps,enrevancheledplacementdelattedelecture
sefaitenuntempsdaccsconsidrablementplusgrand.
Lesalgorithmesdegestiondesentres/
sortiessurdisquedessystmesdexploitationcherchentdoncnaturellementdiminueraumaximum
cesdplacementsenrorganisantenconsquencelesrequtesdelectureetdcriture.
Il est doncgnralement beaucoupplussimpledecompterlenombredoprationsquelesalgo
rithmeseffectuentlorsdeleurdroulement,carcettedonneestbienmoinsspcifiqueaucontexte
dutilisationdelalgorithme.Bienentendu,touteslesoprationseffectuesparunalgorithmenont
paslemmecotdansuncontextedonn,etdepluscecotvarieduncontextedutilisationun
autre.Lacomplexitdunalgorithmedoitdonctoujourssexprimerennombredoprationslmen
tairesduncertaintype,tantentenduquelesoprationsdecetypesontcellesquicotentlepluscher
selonlescritreschoisis...
Remarquezquelesoprationsquisontralisesparunalgorithmepeuventtreellesmmesrelative
mentcomplexes.Parexemple,unalgorithmequiappliqueunefonctionsurchaquedonnetraiter
peututiliserunefonctioninimaginablementcomplexe.Cependant,celanenousintressepasdansla
dterminationdelacomplexitdecetalgorithme.Bienentendu,cequilfautcompter,cestlenombre
defoisquecettefonctionestappele,etlacomplexitdelalgorithmedoitsecalculerindpendam
mentdecelledecettefonction.Loprationlmentairedelalgorithmeestdoncicitoutsimplement
lappeldecettefonction,aussicomplexesoitelle.
13.7.2.Notionsmathmatiquesdebaseetdfinition
Lenombredesoprationslmentaireseffectuesparunalgorithmeest
unefonctiondirectedu
nombrededonnestraiter. Lacomplexitdunalgorithmeest doncdirectement reliecette
fonction: plusellecrot rapidement aveclenombrededonnestraiter,
pluslacomplexitde
lalgorithmeestgrande.
Enralit, lafonctionexactedonnantlenombredoprationslmentaireseffectuesparunalgo
rithmenestpastoujoursfacilecalculer.Cependant,ilexistetoujoursunefonctionplussimplequi
disposedummecomportementquelafonctiondunombredoprationsdelalgorithmequandle
nombrededonnestraiteraugmente. Cetteformesimplifienestenfaitriendautrequela
partiecroissantleplusviteaveclenombrededonnes,carlorsqueceluicitendverslinfini,cest
ellequidevientprdominante.Celasignifiequesilontracelegraphedelafonction,saformefinit
parressemblercelledesaformesimplifielorsquelenombrededonnestraiterdevientgrand.
Laformulationcompltedelafonctiondunombredoprationsralisesparunalgorithmenimporte
doncpastantquecela,cequiestintressant,cestsaformesimplifie.Eneffet,nonseulementelleest
plussimple(exprimer,manipuleretbienvidemmentretenir),maisenplusellecaractrisecor
rectementlecomportementdelalgorithmesurlesgrandsnombres.Lacomplexitdunalgorithme
estdonc,pardfinition,letermeprpondrantdanslafonctiondonnantlenombredoprationsl
mentaireseffectuesparlalgorithmeenfonctiondunombredesdonnestraiter.
230
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
Mathmatiquement parlant, lefait quelaformesimplifiedunefonctionsecomportecommela
fonctionellemmelinfinisetraduitsimplementendisantquelestermesdordreinfrieurssont
crassparletermedepremierordre. Parconsquent, si londiviseunefonctionparlautre, les
termesdordreinfrieurdeviennentngligeablesetlavaleurdurapporttendsestabiliserversles
grandnombres.Autrementdit,ilestpossibledetrouverdeuxconstantes A et B positivesetnonnulles
tellesque,partirdunecertainevaleurde n,latripleinquation0 Ac(n) f(n) Bc(n),
danslaquelle c(n) estlaformesimplifiedelafonctionf(n),esttoujoursvrifie.Lafonctionf(n)
estdonc,enquelquesortes,encadrepardeuxgendarmesquisuiventlemmetrajet:celuide
lafonction c(n).
f(n) et c(n) directement.
Note:Notezquecetteformulationnutilisepaslerapportdesfonctions
Elleestdonctoujoursvalide,mmelorsquecesdeuxfonctionssontnulles,cequiauraitposdes
problmessilonavaitutilisunrapport.
13.7.3.Interprtationpratiquedelacomplexit
Toutescesnotionspeuventvousparatreassezabstraites,maisilestimportantdebiencomprendrece
quellessignifient.Ilestdoncpeuttrencessairededonnerquelquesexemplesdecomplexitparmi
cellesquelonrencontrelepluscouramment.
Tout dabord, unecomplexitde 1 pour unalgorithmesignifietout simplement quesoncot
dexcutionestconstant,quelquesoitlenombrededonnestraiter.Notezbieniciquelonparle
decotdexcutionetnondedure.Lecotesticilenombredoprationslmentaireseffectues
parcetalgorithme.Lesalgorithmesdecomplexit 1 sontvidemmentlesplusintressants,maisils
sonthlasassezraresoutoutsimplementtriviaux.
Gnralement,lesalgorithmesontunecomplexitde n,leurcotdexcutionestdoncproportionnel
aunombrededonnestraiter.Cestencoreunelimiteacceptable,etgnralementacceptecomme
uneconsquencelogiquedelaugmentationdunombrededonnestraiter.Certainsalgorithmes
n2 ,soitlecarrdunombre
sontenrevanchenettementmoinsperformantsetontunecomplexiten
deslmentstraiter. Cettefois, celasignifiequeleurcot dexcutionatendancecrotretrs
rapidementlorsquilyadeplusenplusdedonnes.Parexemple,silondoublelenombrededonnes,
lecot dexcutiondelalgorithmenedoublepas, maisquadruple. Et si lontriplelenombrede
231
Chapitre13.Servicesetnotionsdebasedelabibliothquestandard
donnes,cecotdevientneuffoisplusgrand.Necroyezpaspourautantquelesalgorithmesdece
typesoientraresoumauvais.Onnepeutpastoujours,hlas,faireautrement...
Ilexistemmedesalgorithmesencorepluscoteux,quiutilisentdesexposantsbiensuprieurs2.
Inversement,certainsalgorithmesextrmementastucieuxpermettentderduirelescomplexits n ou
n2 en ln(n) ou nln(n),ilssontdoncnettementplusefficaces.
Note: Lafonction ln(n) est lafonctionlogarithmique, qui est lafonctioninversede
lexponentielle, bienconnuepour sacroissancedmesure. Lafonctionlogarithmevolue
beaucoupmoinsvitequesonargument,enloccurrence n dansnotrecas,etadonctendance
craserlecotdesalgorithmesquilontpourcomplexit.
Enfin,pourterminercesquelquesnotionsdecomplexitalgorithmique,sachezquelonpeutvaluer
ladifficultdunproblmepartirdelacomplexitdumeilleuralgorithmequipermetdelersoudre.
Parexemple,ilatdmontrqueletridunensemblede n lmentsnepeutpassefaireenmieux
que nln(n) oprations(etonsaitlefaire, cequiestsansdouteleplusintressantdelaffaire).
Malheureusement, ilnestpastoujoursfacilededterminerlacomplexitdunproblme.
Ilexiste
mmetouteuneclassedeproblmesextrmementdifficilesrsoudrepourlesquelsonnesaitmme
passi leursolutionoptimaleest polynomialeounon. Enfait, onnesait lesrsoudrequavecdes
algorithmesdecomplexitexponentielle(sivousnesavezpascequecelasignifie,enunmot,cela
veutdirequecestunevritablecatastrophe).Cependant,celaneveutpasforcmentdirequonne
peutpasfairemieux,maistoutsimplementquonnapasputrouverunemeilleuresolution,nimme
prouverquilyenavaitune!Toutefois, touscesproblmessontliset, siontrouveunesolution
polynomialepourlundentreeux,onsaurarsoudreaussifacilementtoussespetitscamarades.Ces
problmesappartiennenttouslaclassedesproblmesditsNPcomplets.
232
Chapitre14.Lestypescomplmentaires
LeC++tant unlangagebassurleC, il souffredesmmeslimitationsconcernant lestypesde
donnesavancsqueceluici. Pourpalliercet inconvnient, labibliothquestandardC++dfinit
destypescomplmentairessousformedeclassesC++,ventuellement template,etpermettantde
satisfaireauxbesoinslespluscourants. Parmicestypes, onnoteraavanttoutletypebasic_string,
quipermetdemanipulerleschanesdecaractresdemanireplussimpleetplussrequavecdes
pointeursetdestableauxdecaractres.Maislabibliothquestandarddfinitgalementdesclasses
utilitairesquipermettentdemanipulerlesautrestypesplusfacilement,ainsiquedestypescapables
dutilisertouteslesressourcesdelamachinepourlescalculsnumriquesavancs.
14.1.Leschanesdecaractres
Laclasse template basic_stringdelabibliothquestandard,dclaredanslenttestring,facilite
letravailduprogrammeuretpermetdcrireducodemanipulantdestextesdemanirebeaucoup
plussre. Eneffet, cetteclasseencapsuleleschanesdecaractresCclassiquesetfournissentdes
servicesextrmementintressantsquintaientpasdisponiblesauparavant.Enparticulier,laclasse
basic_stringdisposedescaractristiquessuivantes:
compatibilitquasitotaleavecleschanesdecaractresCstandards;
gestiondeschanestaillevariable;
priseenchargedelallocationdynamiquedelammoireetdesalibrationenfonctiondesbesoins
etdelatailledeschanesmanipules;
dfinitiondesoprateursdeconcatnation,
cherchedansleschanesdecaractres;
intgrationtotaledanslabibliothquestandard,enparticulierauniveaudesfluxdentre/sortie.
decomparaisonet desprincipalesmthodesdere
Commeillatditplushaut,laclassebasic_stringestuneclasse template.Celasignifiequelle
estcapabledeprendreenchargedeschanesdenimportequeltypedecaractre.Pourcela,ellene
sebasequesurlaclassedestraitsdutypedecaractremanipul.Ilestdoncparfaitementpossible
delutiliseravecdestypesdfinisparlutilisateur, pourvuquelaclassedestraitsdescaractres
soitdfiniepourcestypes. Bienentendu, laclassebasic_stringpeuttreutiliseaveclestypesde
caractresdulangage,savoircharetwchar_t.
Lesdclarationsdelentte string sontessentiellementlessuivantes:
template <classcharT,classtraits=char_traits
<charT>,
classAllocator=allocator
<charT>>
classbasic_string
{
public:
//Types
typedeftraits
traits_type;
typedeftypenametraits::char_typevalue_type;
typedefAllocator
allocator_type;
typedeftypenameAllocator::size_type
size_type;
typedeftypenameAllocator::difference_typedifference_type;
typedeftypenameAllocator::reference
reference_type;
typedeftypenameAllocator::const_referenceconst_reference;
233
Chapitre14.Lestypescomplmentaires
typedeftypenameAllocator::pointer
typedeftypenameAllocator::const_pointer
pointer;
const_pointer;
//Constanteutiliseeninterneetreprsentantlavaleurmaximale
//dutypesize_type:
staticconstsize_typenpos=static_cast <size_type>(1);
//Constructeursetdestructeur:
explicitbasic_string(constAllocator&allocateur=Allocator());
basic_string(constbasic_string&source,size_typedebut=0,
size_typefin=npos,constAllocator&allocateur=Allocator());
basic_string(constcharT*chaine,size_typenombre,
constAllocator&allocateur=Allocator());
basic_string(constcharT*chaine,
constAllocator&allocateur=Allocator());
basic_string(size_typenombre,charTcaractere,
constAllocator&allocateur =Allocator());
template <classInputIterator>
basic_string(InputIteratordebut,InputIteratorfin,
constAllocator&allocateur =Allocator());
~basic_string();
//Itrateurs:
typedeftype_priviterator;
typedeftype_privconstiterator;
typedefstd::reverse_iterator
<iterator> reverse_iterator;
typedefstd::reverse_iterator
<const_iterator> const_reverse_iterator;
iterator
begin();
const_iteratorbegin()const;
iterator
end();
const_iteratorend()const;
reverse_iterator
rbegin();
const_reverse_iteratorrbegin()const;
reverse_iterator
rend();
const_reverse_iteratorrend()const;
//Accesseurs:
size_typesize()const;
size_typelength()const;
size_typemax_size()const;
size_typecapacity()const;
boolempty()const;
allocator_typeget_allocator()const;
//Manipulateurs:
voidresize(size_typetaille,charTcaractere);
voidresize(size_typetaille);
voidreserve(size_typetaille=0);
//Accsauxdonnesdelachane:
const_referenceoperator[](size_typeindex)const;
referenceoperator[](size_typeindex);
const_referenceat(size_typeindex)const;
referenceat(size_typeindex);
constcharT*c_str()const;
constcharT*data()const;
size_typecopy(charT*destination,size_typetaille,
234
Chapitre14.Lestypescomplmentaires
size_typedebut=0)const;
basic_stringsubstr(size_typedebut=0,size_typetaille=npos)const;
//Affectation:
basic_string&operator=(constbasic_string&source);
basic_string&operator=(constcharT*source);
basic_string&operator=(charTcaractere);
basic_string&assign(constbasic_string&source);
basic_string&assign(constbasic_string&source,
size_typeposition,size_typenombre);
basic_string&assign(constcharT*chaine,size_typenombre);
basic_string&assign(constcharT*chaine);
basic_string&assign(size_typenombre,charTcaractere);
template <classInputIterator>
basic_string&assign(InputIteratordebut,InputIteratorfin);
//Concatnationetajout:
basic_string&operator+=(constbasic_string&source);
basic_string&operator+=(constcharT*chaine);
basic_string&operator+=(charTcaractere);
basic_string&append(constbasic_string&source);
basic_string&append(constbasic_string&source,
size_typeposition,size_typenombre);
basic_string&append(constcharT*chaine,size_typenombre);
basic_string&append(constcharT*chaine);
basic_string&append(size_typenombre,charTcaractere);
template <classInputIterator>
basic_string&append(InputIteratordebut,InputIteratorfin);
//Insertionetextraction:
basic_string&insert(size_typeposition,constbasic_string&source);
basic_string&insert(size_typeposition,constbasic_string&source,
size_typedebut,size_typenombre);
basic_string&insert(size_typeposition,constcharT*chaine,
size_typenombre);
basic_string&insert(size_typeposition,constcharT*chaine);
basic_string&insert(size_typeposition,size_typenombre,
charTcaractere);
iteratorinsert(iteratorposition,charTcaractere=charT());
voidinsert(iteratorposition,size_typenombre,charTcaractere);
template <classInputIterator>
voidinsert(iteratorposition,InputIteratordebut,InputIteratorfin);
//Suppression:
basic_string&erase(size_typedebut=0,size_typefin=npos);
iteratorerase(iteratorposition);
iteratorerase(iteratordebut,iteratorfin);
voidclear();
//Remplacementetchange:
basic_stringreplace(size_typeposition,size_typelongueur,
constbasic_string&remplacement);
basic_stringreplace(size_typeposition,size_typelongueur,
constbasic_string&remplacement,size_typedebut,
size_typetaille);
basic_string&replace(size_typeposition,size_typelongueur,
constcharT*remplacement,size_typetaille);
235
Chapitre14.Lestypescomplmentaires
basic_string&replace(size_typeposition,size_typelongueur,
constcharT*remplacement);
basic_string&replace(size_typeposition,size_typelongueur,
size_typenombre,charTcaractere);
basic_string&replace(iteratordebut,iteratorfin,
constbasic_string&remplacement);
basic_string&replace(iteratordebut,iteratorfin,
constcharT*remplacement,size_typetaille);
basic_string&replace(iteratordebut,iteratorfin,
constcharT*remplacement);
basic_string&replace(iteratordebut,iteratorfin,
size_typenombre,charTcaractere);
template <classInputIterator>
basic_string&replace(iteratordebut,iteratorfin,
InputIteratordebut_remplacement,InputIteratorfin_remplacement);
voidswap(basic_string<charT,traits,Allocator> &chaine);
//Comparaison:
intcompare(constbasic_string&chaine)const;
intcompare(size_typedebut1,size_typelongueur1,
constbasic_string&chaine,
size_typedebut2,size_typelongueur2)const;
intcompare(constcharT*chaine)const;
intcompare(size_typedebut,size_typelongueur,constcharT*chaine,
size_typetaille=npos)const;
//Recherche:
size_typefind(constbasic_string&motif,
size_typeposition=0)const;
size_typefind(constcharT*motif,size_typeposition,
size_typetaille)const;
size_typefind(constcharT*motif,size_typeposition=0)const;
size_typefind(charTcaractere,size_typeposition=0)const;
size_typerfind(constbasic_string&motif,
size_typeposition=npos)const;
size_typerfind(constcharT*motif,size_typeposition,
size_typetaille)const;
size_typerfind(constcharT*motif,size_typeposition=npos)const;
size_typerfind(charTcaractere,size_typeposition=npos)const;
size_typefind_first_of(constbasic_string&motif,
size_typeposition=0)const;
size_typefind_first_of(constcharT*motif,size_typeposition,
size_typetaille)const;
size_typefind_first_of(constcharT*motif,
size_typeposition=0)const;
size_typefind_first_of(charTcaractere,size_typeposition=0)const;
size_typefind_last_of(constbasic_string&motif,
size_typeposition=npos)const;
size_typefind_last_of(constcharT*motif,size_typeposition,
size_typetaille)const;
size_typefind_last_of(constcharT*motif,
size_typeposition=npos)const;
size_typefind_last_of(charTcaractere,
size_typeposition=npos)const;
size_typefind_first_not_of(constbasic_string&motif,
size_typeposition=0)const;
size_typefind_first_not_of(constcharT*motif,size_typeposition,
236
Chapitre14.Lestypescomplmentaires
size_typetaille)const;
size_typefind_first_not_of(constcharT*motif,
size_typeposition=0)const;
size_typefind_first_not_of(charTcaractere,
size_typeposition=0)const;
size_typefind_last_not_of(constbasic_string&motif,
size_typeposition=npos)const;
size_typefind_last_not_of(constcharT*motif,size_typeposition,
size_typetaille)const;
size_typefind_last_not_of(constcharT*motif,
size_typeposition=npos)const;
size_typefind_last_not_of(charTcaractere,
size_typeposition=npos)const;
};
typedefbasic_string<char>
string;
typedefbasic_string<wchar_t> wstring;
14.1.1.Constructionetinitialisationdunechane
Lamanirelaplussimpledeconstruireunebasic_stringestsimplementdeladclarer, sanspara
mtres. Celaapourconsquencedappelerleconstructeurpardfaut, etdinitialiserlachanela
chanevide.
Enrevanche,sivousdsirezinitialisercettechane,plusieurspossibilitssoffrentvous.Outrele
constructeurdecopie,quipermetdecopieruneautrebasic_string,ilexisteplusieurssurchargesdu
constructeurpermettantdinitialiserlachanedediffrentesmanires.Leconstructeurleplusutilis
serasansaucundouteleconstructeurquiprendenparamtreunechanedecaractresCclassique:
stringchaine("Valeurinitiale");
Ilexistecependantunevariantedececonstructeur,quiprendenparamtrelenombredecaractres
delachanesourceutiliserpourlinitialisationdelabasic_string.Ceconstructeurdevratreutilis
danslecasdestableauxdecaractres, qui contiennent deschanesdecaractresqui nesont pas
ncessairementterminesparuncaractrenul:
stringchaine("Valeurinitiale",6);
237
Chapitre14.Lestypescomplmentaires
caractresuivantlederniercaractreutiliser.Bienentendu,cesdeuxitrateurssontdesimplespoin
teursdecaractressilescaractresdevantservirlinitialisationsontdansunechanedecaractres
Coudansuntableaudecaractres.Cependant,cepeuttredesitrateursdunconteneurquelconque,
pourvuqueceluicicontiennebienunesquencedecaractresetqueledeuximeitrateursetrouve
bienaprslepremierdanscettesquence.Notezqueledeuximeitrateurnerfrencepasledernier
caractredelasquencedinitialisation,maisbienlecaractresuivant.Ilpeutdoncvaloirlavaleur
defindelitrateurduconteneursource.Ainsi,lecodesuivant:
char*source="Valeurinitiale";
strings(source,source+6);
astrictementlemmeeffetqueceluidelexempleprcdent.
Enfin,ilexisteunconstructeurdontlebutestdinitialiserunebasic_stringavecunesuitedecaractres
identiquesdunecertainelongueur.Ceconstructeurnestrellementpasdifficileutiliser,puisquil
suffitdeluifournirenparamtrelenombredecaractresquelabasic_stringdevraconteniretlavaleur
ducaractrequidevratrerptdanscettechane.
Vousremarquerezquetouscesconstructeursprennentendernierparamtreuneinstancedallocateur
mmoireutiliserpourlesoprationsdallocationetdelibrationdelammoirequelachaneest
susceptibledavoirfaire.Vouspouvezspcifieruneinstancequelconque,ouutiliserlavaleurpar
dfautfournieparlesdclarationsdesconstructeurs.Cettevaleurpardfautesttoutsimplementune
instancetemporairedelallocateurspcifienparamtre template delaclassebasic_string. Par
dfaut,cetallocateurestlallocateurstandard,pourlequeltouteslesinstancespermettentdaccder
lammemmoire.Ilnestdoncpasncessairedespcifierlinstanceutiliser,puisquellessont
toutesfonctionnellementidentiques.Enpratiquedonc,ilesttrsraredavoirspcifierunallocateur
mmoiredanscesconstructeurs.
14.1.2.Accsauxpropritsdunechane
Laclassebasic_stringfournituncertainnombredaccesseurspermettantdobtenirdesinformations
sursontatetsurlachanedecaractresquellecontient.Lunedesinformationslesplusintressantes
estsansnuldoutelalongueurdecettechane. Ellepeuttreobtenuelaidededeuxaccesseurs,
quisontstrictementquivalents: size et length.Vouspouvezutiliserlunoulautre,selonvotre
convenance.Parailleurs,sivousdsirezsimplementsavoirsilabasic_stringestvide,vouspouvez
appelerlamthode empty.
Note:Attention,contrairementcequesonnompourraitlaisserpenser,lamthode empty ne
videpaslabasic_string!
Lataillemaximalequunebasic_stringpeutcontenirestsouventdirectementlielaquantitde
mmoiredisponible,puisquelachanedecaractresquellecontientestallouedynamiquement.Il
nyadoncsouventpasbeaucoupdintrtobtenircettetaille,maisvouspouvezmalgrtoutlefaire,
grcelamthode max_size.
Laquantitdemmoirerellementalloueparunebasic_stringpeuttresuprieurelalongueur
delachanedecaractrescontenue. Eneffet, laclassebasic_stringpeut conserverunemargede
manoeuvre,pourlecasolachanedevraittreagrandielasuiteduneoprationparticulire.Cela
permetderduirelesrallocationsdemmoire,quipeuventtretrscoteuseslorsquelammoire
sefragmente(lachanedoittrerecopieversunnouvelemplacementsiunautreblocmmoirese
trouvejusteaprsleblocmmoirerallouer).Cettequantitdemmoirepeuttreobtenuelaide
238
Chapitre14.Lestypescomplmentaires
delamthode capacity. Nousverronscommentrserverdelaplacemmoireenprvisiondun
redimensionnementultrieurdanslasectionsuivante.
Danslecasovousutiliseriezunallocateurdiffrentdelallocateurpardfaut,vouspouvezobtenir
get_allocator. Ilestrelativementraredavoir
unecopiedecetallocateurgrcelamthode
utilisercettemthode.
14.1.3.Modificationdelatailledeschanes
Unefoisquunebasic_stringatconstruite, ilestpossibledelamodifieraposterioripourlar
duire,lagrandirouaugmentersacapacit.Cesoprationspeuventtreraliseslaidedemthodes
fourniesceteffet.
Lamthode resize permet demodifierlatailledelachanedecaractresstockedanslaba
sic_string. Danssaversionlaplussimple, elleprendenparamtrelanouvelletaillequelachane
doitavoir.Sicettetailleestinfrieurelataillecourante,lachaneesttronque.Enrevanche,sicette
tailleestsuprieurelatailleactuelle,lachaneesttendueetlesnouveauxcaractressontinitiali
ssaveclavaleurdescaractresdfinieparleconstructeurpardfautdeleurclasse.Pourlestypes
prdfinischaretwchar_t, cettevaleuresttoujourslecaractrenul. Lesdonnesstockesdansla
basic_stringreprsententdonctoujourslammechanedecaractresC,puisqueceschanesutilisent
lecaractrenulcommemarqueurdefindechane.Ainsi,lalongueurrenvoyeparlamthode size
peuttrediffrentedelalongueurdelachaneCcontenueparlabasic_string.
Exemple141.Redimensionnementdunechane
#include <iostream>
#include <string>
#include <string.h>
usingnamespacestd;
intmain(void)
{
strings("123");
s.resize(10);
cout << s << endl;
//Lanouvelletaillevautbien10:
cout << "Nouvelletaille:" << s.length() << endl;
//maislalongueurdelachaneCreste3:
cout << "LongueurC:"
<< strlen(s.c_str()) << endl;
return0;
}
Note:Lamthode c_str utilisedanscetexempleseradcriteendtaildanslasectionsuivante.
EllepermetdobtenirladressedelachaneCstockeeninternedanslabasic_string.
Lafonction strlen quantelleestunedesfonctionsdemanipulationdeschanesdecaractres
delabibliothqueC. Elleest dfiniedanslefichierdentte string.h (quelonneconfondra
pasaveclentte string delabibliothquestandardC++),etrenvoielalongueurdelachane
decaractresquiluiestfournieenparamtre.
resize nest
Silavaleurpardfaututilisepourlescaractrescomplmentairesdanslamthode
pascellequiestdsire,ilfautenutiliseruneautreversion.Cettedeuximeversionprend,enplus
239
Chapitre14.Lestypescomplmentaires
delanouvelletailledelachanedecaractres,lecaractrederemplissageutiliserpourlecasola
nouvelletailleseraitsuprieurelatailleinitialedelachane:
strings("123");
s.resize(10,a);
14.1.4.Accsauxdonnesdelachanedecaractres
Lescaractresdesbasic_stringpeuventtreaccdsdenombreusesmanires.Premirement,laclasse
basic_stringsurchargeloprateurdaccsauxlmentsduntableau,etlonpourralesutiliserpour
obtenirunerfrenceundescaractresdelachanepartirdesonindice.Cetoprateurnestdfini
quepourlesindicesvalidesdanslachanedecaractres,savoirlesindicesvariantde0lavaleur
retourneparlamthode size delachanemoinsun:
#include <iostream>
#include <string>
240
Chapitre14.Lestypescomplmentaires
usingnamespacestd;
intmain(void)
{
strings("azc");
//Remplaceledeuximecaractredelachaneparunb:
s[1]=b;
cout << s << endl;
return0;
}
Lorsquilestappliquunebasic_stringconstante, loprateurtableaupeutrenvoyerlavaleurdu
caractredontlindiceestexactementlatailledelachane.
Ilsagitvidemmentducaractrenul
servant demarqueurdefindechane. Enrevanche, larfrencerenvoyeparcet oprateurpour
touteslesautresvaleurs,ainsiqueparloprateurtableauappliquauxchanesnonconstantepour
lecaractredefindechanenesontpasvalides.Lecomportementdesprogrammesquieffectuentde
telsaccsestimprvisible.
Ilexisteuneautrepossibilitpouraccderauxcaractresdunebasic_string.Ilsagitdelamthode
at.Contrairementloprateurtableau,cettemthodepermetdeffectueruncontrlesurlavalidit
delindiceutilis.Ellerenvoie,commeloprateurdetableaudelaclassebasic_string,larfrence
ducaractredontlindiceestspcifienparamtre.Cependant,elleeffectueaupralableuncontrle
surlavaliditdecetindice,quidoittoujourstrestrictementinfrieurlatailledelachane.Dansle
cascontraire,lamthode at lanceuneexceptionout_of_range:
#include <iostream>
#include <string>
#include <stdexcept>
usingnamespacestd;
intmain(void)
{
strings("01234");
try
{
s.at(5);
}
catch(constout_of_range&)
{
cout << "Dbordement!" << endl;
}
return0;
}
Laclassebasic_stringnecontientpasdoprateurdetranstypageverslestypesdeschanesdecarac
tresCclassique,savoirletypepointeursurcaractreetpointeursurcaractreconstant.Cestun
choixdeconception,quipermetdviterlesconversionsimplicitesdesbasic_stringenchaneCclas
sique,quipourraienttreextrmementdangereuses.Eneffet,cesconversionsconduiraientobtenir
implicitementdespointeursquineseraientplusvalidesdsquuneoprationseraiteffectuesurla
basic_stringsource.Cependant,laclassebasic_stringfournitdeuxmthodespermettantdobtenirde
telspointeursdemanireexplicite.Leprogrammeurprenddoncsesresponsabilitslorsquilutilise
cesmthodes,etestsuppossavoirdansquelcontextecespointeurssontvalides.
241
Chapitre14.Lestypescomplmentaires
Cesdeuxmthodessontrespectivementlamthodedata etlamthode c_str.Lapremiremthode
renvoieunpointeursurlesdonnesdelabasic_string.Cesdonnesnesontriendautrequuntableau
decaractres, dontladimensionestexactementlavaleurretourneparlamthode size ouparla
mthode length.Cetableaupeutcontenirdescaractresdeterminaisondechane,siparexemple
unetellevaleuratcriteexplicitement ouatintroduitesuiteunredimensionnement dela
chane.Lamthode c_str enrevancheretourneunpointeursurlachanedecaractresCcontenue
danslabasic_string. Contrairement auxdonnesrenvoyesparlamthode data, cettechaneest
ncessairementtermineparuncaractredefindechane.Cettemthodeseradoncutilisepartout
olonveutobtenirunechanedecaractresCclassique, maisellenedevrapastreutilisepour
accderauxdonnessituesaprscecaractredefindechane.
Exemple143.Accsdirectauxdonnesdunechane
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings("123456");
//LachaneCestcoupeautroisimecaractre:
s[3]=0;
cout << s.c_str() << endl;
//Maisonpeutquandmmeobtenirlescaractressuivants:
cout << s.data()[4] << s.data()[5] << endl;
return0;
}
Notezquecesmthodesrenvoientdespointeurssurdesdonnesconstantes.Celaestnormal,caril
estabsolumentinterditdemodifierlesdonnesinterneslabasic_stringquiafournicespointeurs.
Vousnedevezdoncenaucuncasessayerdcriredanscestableauxdecaractres,mmeenfaisant
untranstypageaupralable.
Enfin,laclassebasic_stringdfinitdesitrateursaccsalatoirespermettantdaccdersesdonnes
commesilsagissaitdunechanedecaractresstandard. Lesmthodes begin et end permettent
dobtenirrespectivementunitrateursurlepremiercaractredelachaneetlavaleurdefindece
mmeitrateur.Demme,lesmthodes rbegin et rend permettentdeparcourirlesdonnesdela
basic_stringensensinverse.Prenezgardeaufaitquecesitrateursnesontvalidesquetantquaucune
mthodemodifiantlachanenestappele.
14.1.5.Oprationssurleschanes
Laclassebasic_stringfournittoutunensembledemthodespermettantdeffectuerlesoprationsles
pluscourantessurleschanesdecaractres.Cestcetensembledemthodesquifonttoutlintrt
decetteclasseparrapportauxchanesdecaractresclassiquesdulangageC,carellesprennenten
chargeautomatiquementlesallocationsmmoireetlescopiesdechanesquelimplmentationdeces
fonctionnalitspeutimposer. Cesoprationscomprennentlaffectationetlaconcatnationdedeux
chanesdecaractres,lextractiondunesouschane,ainsiquelasuppressionetleremplacementde
caractresdansunechane.
242
Chapitre14.Lestypescomplmentaires
14.1.5.1.Affectationetconcatnationdechanesdecaractres
Plusieurs surcharges deloprateur daffectationsont dfinies dans laclassebasic_string. Ces
surchargespermettent daffecterunenouvellevaleurunechane, enremplaant ventuellement
lanciennevaleur.Danslecasdunremplacement,lammoireconsommeparlanciennevaleurest
automatiquementrutiliseoulibresiunerallocationestncessaire.Cesoprateursdaffectation
peuventprendreenparamtreuneautrebasic_string,unechanedecaractresCclassiqueoumme
unsimplecaractre. Leurutilisationest doncdirecte, il suffit simplement dcrireuneaffectation
normale.
Ilestimpossible, avecloprateurdaffectation, defournirdesparamtressupplmentairescomme
ceuxdontlesconstructeursdelaclassebasic_stringdisposentparexemple.Cestpourcetteraison
quuneautremthode,lamthode assign,atdfiniepourpermettredefairedesaffectationsplus
complexes.
Lespremiresversionsdecesmthodespermettentbienentendudeffectuerlaffectationduneautre
basic_stringoudunechanedecaractresCclassique.Cependant,ilestgalementpossibledesp
cifierlalongueurdelaportiondechanecopierendeuximeparamtrepourleschanesC,etla
positionainsiquelenombredecaractrescopierdanslecasdunebasic_string.Ilestgalement
possiblederinitialiserunebasic_stringavecuncaractrespcifique, endonnantetlenombrede
caractresdupliquerdanslachaneenpremierparamtreetlavaleurdececaractreendeuxime
paramtre. Enfin, il existeuneversion template decettemthodepermettant daffecterlaba
sic_stringlasquencedecaractrescomprisentredeuxitrateursdunconteneur.
Exemple144.Affectationdechanedecaractres
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings1,s2;
char*p="1234567890";
//Affecte"345"s1:
s1.assign(p+2,p+6);
cout << s1 << endl;
//Affectelesdeuxpremierscaractresdes1s2:
s2.assign(s1,0,2);
cout << s2 << endl;
//Rinitialises1avecdesA:
s1.assign(5,A);
cout << s1 << endl;
return0;
}
Demaniresimilaire,loprateurdaffectationavecaddition +=atsurchargafindepermettre
lesconcatnationsdechanesdecaractresdemanireintuitive.Cetoprateurpermetdajouteraussi
bienuneautrebasic_stringquunechanedecaractresCclassiqueouununiquecaractrelafin
dunebasic_string.Commecetoprateuresttroprestrictiflorsquilsagitdeconcatnerunepartie
append atdfini.Cesm
seulementduneautrechaneunebasic_string,unjeudemthodes
thodespermettentdajouterunebasic_stringuneautrebasic_stringouunechanedecaractresC
bienentendu,maisaussidajouterunepartieseulementdeceschanesouunnombredterminde
caractres.Toutescesmthodesprennentlesmmesparamtresquelesmthodes assign correspon
dantesetleuremploinedevraitpasposerdeproblmeparticulier.
243
Chapitre14.Lestypescomplmentaires
Exemple145.Concatnationdechanesdecarctres
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings1="abcef";
strings2="ghijkl";
//Utilisationdeloprateurdeconcatnation:
s1+=s2;
cout << s1 << endl;
//Utilisationdelamthodeappend:
s1.append("mnopq123456",5);
cout << s1 << endl;
return0;
}
14.1.5.2.Extractiondedonnesdunechanedecaractres
Nousavonsvuquelesmthodes data et c_str permettaientdobtenirdespointeurssurlesdonnes
desbasic_string.Cependant,ilestinterditdemodifierlesdonnesdelabasic_stringautraversdeces
pointeurs.Or,ilpeuttreutile,danscertainessituations,davoirtravaillersurcesdonnes,ilfaut
doncpouvoirenfaireunecopietemporaire. Cestcequepermetlamthode copy. Cettefonction
prendenparamtreunpointeursurunezonedemmoiredevantaccueillirlacopiedesdonnesdela
basic_string,lenombredecaractrescopier,ainsiquelenumroducaractredelabasic_string
partirduquellacopiedoitcommencer.Cedernierparamtreestfacultatif,carilprendpardfautla
valeur0(lacopiesefaitdoncpartirdupremiercaractredelabasic_string.
Exemple146.Copiedetravaildesdonnesdunebasic_string
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings="1234567890";
//Copielachanedecaractresdansunezonedetravail:
charbuffer[16];
s.copy(buffer,s.size(),0);
buffer[s.size()]=0;
cout << buffer << endl;
return0;
}
Labasic_stringdoitcontenirsuffisammentdecaractrespourquelacopiepuissesefaire.Sicenest
paslecas, ellelancerauneexceptionout_of_range. Enrevanche, lamthode copy nepeut faire
aucunevrificationquantlaplacedisponibledanslazonemmoirequiluiestpasseenparamtre.
Ilestdoncdelaresponsabilitduprogrammeurdesassurerquecettezoneestsuffisammentgrande
pouraccueillirtouslescaractresquildemande.
244
Chapitre14.Lestypescomplmentaires
Lamthode copy permet dobtenirlacopiedunesouschanedelachanecontenuedanslaba
sic_string.Toutefois,silonveutstockercettesouschanedansuneautrebasic_string,ilnefautpas
utilisercettemthode.Lamthode substr permeteneffetdeffectuercetravaildirectement.Cette
mthodeprendenpremierparamtrelenumrodupremiercaractrepartirdelasouschaneco
pier,ainsiquesalongueur.Commepourlamthodecopy,ilfautquelabasic_stringsourcecontienne
suffisammentdecaractresfautedequoiuneexceptionout_of_rangeseralance.
Exemple147.Extractiondesouschane
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings1="1234567890";
strings2=s1.substr(2,5);
cout << s2 << endl;
return0;
}
14.1.5.3.Insertionetsuppressiondecaractresdansunechane
Laclassebasic_stringdisposedetoutunjeudemthodesdinsertiondecaractresoudechanesde
caractresauseindunebasic_stringexistante.Toutescesmthodessontdessurchargesdelamthode
insert.Cessurchargesprennenttoutesunparamtreenpremirepositionquiindiquelendroito
linsertiondoittrefaite.Ceparamtrepeuttresoitunnumrodecaractre,indiquparunevaleur
detypesize_type,soitunitrateurdelabasic_stringdanslaquellelinsertiondoittrefaite.Lesautres
paramtrespermettentdespcifiercequidoittreinsrdanscettechane.
Lesversionslesplussimplesdelamthode insert prennentendeuximeparamtreuneautreba
sic_stringouunechanedecaractresCclassique.Leurcontenuserainsrlemplacementindiqu.
Lorsqueledeuximeparamtreestunebasic_string,ilestpossibledindiquerlenumrodupremier
caractreainsiquelenombredecaractrestotalinsrer.Demme,lorsdelinsertiondunechane
Cclassique,ilestpossibledindiquerlenombredecaractresdecettechanequidoiventtreinsrs.
Ilexisteaussidesmthodes insert permettantdinsrerunouplusieurscaractresunemplacement
donndanslachanedecaractres.Cecaractredoitalorsspcifiendeuximeparamtre,saufsi
lonveutinsrerplusieurscaractresidentiquesdanslachane,auquelcasondoitindiquerlenombre
decaractresinsreretlavaleurdececaractre.
Enfin, il existeuneversiondelamthode insert qui prendenparamtre, enplusdelitrateur
spcifiantlapositionpartirdelaquellelinsertiondoittrefaitedanslabasic_string,deuxautresit
rateursdunquelconqueconteneurcontenantdescaractres.Utilisavecdespointeursdecaractres,
cetitrateurpeuttreutilispourinsrerunmorceauquelconquedechanedecaractresCdansune
basic_string.
Toutescesmthodesrenvoientgnralementlabasic_stringsurlaquelleilstravaillent,sauflesm
thodesquiprennentenparamtreunitrateur.Cesmthodessupposenteneffetquelamanipulation
delachanedecaractressefaitparlintermdiairedecetitrateur,etnonparlintermdiairedune
rfrencesurlabasic_string.Cependant,lamthodeinsert permettantdinsreruncaractreunique
unemplacementspcifiparunitrateurrenvoielavaleurdelitrateurrfrenantlecaractrequi
vientdtreinsrafindepermettredercuprercenouvelitrateurpourlesoprationsultrieures.
245
Chapitre14.Lestypescomplmentaires
Exemple148.Insertiondecaractresdansunechane
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings="abef";
//Insreuncetund:
s.insert(2,"cdze",2);
//Idempourgeth,maisavecunebasic_string:
stringgh="gh";
s.insert(6,gh);
cout << s << endl;
return0;
}
Ilexistegalementtroissurchargesdelamthode erase,dontlebutestdesupprimerdescaractres
dansunechaneendcalantlescaractressuivantlescaractressupprimspourremplirlespositions
ainsilibres.Lapremiremthode erase prendenpremierparamtrelapositiondupremiercarac
treetlenombredescaractressupprimer.Ladeuximemthodefonctionnedemaniresimilaire,
maisprendenparamtrelitrateurdedbutetlitrateurdefindelasouschanedecaractresqui
doittresupprime.Enfin,latroisimeversionde erase permetdesupprimerununiquecaractre,
dontlapositionestspcifieencoreunefoisparunitrateur.Cesdeuxderniresmthodesrenvoient
litrateurrfrenantlecaractresuivantlederniercaractrequiatsupprimdelachane.Silny
avaitpasdecaractresaprslederniercaractreeffac,litrateurdefindechaneestrenvoy.
Enfin, ilexisteunemthodeddiepourleffacementcompletdelachanedecaractrescontenue
dansunebasic_string.Cettemthodeestlamthode clear.
Exemple149.Suppressiondecaractresdansunechane
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings="abcdeerrfgh";
//Supprimelafautedefrappe:
s.erase(5,3);
cout << s << endl;
//Effacelachanedecaractrescomplte:
s.clear();
if(s.empty())cout << "Vide!" << endl;
return0;
}
246
Chapitre14.Lestypescomplmentaires
14.1.5.4.Remplacementsdecaractresdunechane
Commepour linsertiondechanesdecaractres,
il existetout unjeudefonctionspermettant
deffectuerunremplacementdunepartiedelachanedecaractresstockedanslesbasic_stringpar
uneautrechanedecaractres. Cesmthodessontnommes replace etsonttoutfaitsimilaires
dansleprincipeauxmthodes insert.Cependant,contrairementcellesci,lesmthodes replace
prennent unparamtresupplmentairepour spcifier lalongueur oulecaractredefindela
souschaneremplacer.Ceparamtredoittrefournijusteaprslepremierparamtre,quiindique
toujourslecaractrededbut delasouschaneremplacer. Il peut tredetypesize_typepour
lesversionsde replace qui travaillent avecdesindices, outreunitrateur, pourlesversions
de replace qui travaillent avecdes itrateurs. Les autres paramtres des fonctions replace
permettentdedcrirelachanederemplacement,etfonctionnentexactementcommelesparamtres
correspondantsdesfonctions insert.
Exemple1410.Remplacementdunesouschanedansunechane
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings="abcerfg";
//Remplaceleeetlerparundetune:
s.replace(3,2,"de");
cout << s << endl;
return0;
}
247
Chapitre14.Lestypescomplmentaires
return0;
}
14.1.6.Comparaisondechanesdecaractres
Lacomparaisondesbasic_stringsebasesurlamthode compare,dontplusieurssurchargesexistent
afindepermettredescomparaisonsdiverseset varies. Lesdeuxversionslesplussimplesdela
mthode compare prennentenparamtresoituneautrebasic_string,soitunechanedecaractresC
classique.Elleseffectuentdonclacomparaisondelabasic_stringsurlaquelleellessappliquentavec
ceschanes.Ellesutilisentpourcelalamthode eq delaclassedestraitsdescaractresutilisspar
lachane.Silesdeuxchanesnediffrentqueparleurtaille,lachanelapluscourteseradclare
infrieurelachanelapluslongue.
Lesdeuxautresmthodes compare permettentdeffectuerlacomparaisondesouschanesdecarac
tresentreelles.Ellesprennenttouteslesdeuxlindiceducaractrededbutetlindiceducaractre
defindelasouschanedelabasic_stringsurlaquelleellessontappliques,untroisimeparamtre
indiquantuneautrechanedecaractres,etdesindicesspcifiantladeuximesouschanedanscette
chane.Siletroisimeargumentestunebasic_string,ilfautspcifiergalementlindicededbutet
lindicedefindelasouschane.Enrevanche,silsagitdunechaneCclassique,ladeuximesous
chanecommencetoujoursaupremiercaractredecettechane,etilnefautspcifierquelalongueur
decettesouschane.
Lavaleurrenvoyeparlesmthodescompare estdetypeentier.Cetentierestnulsilesdeuxchanes
sontstrictementgales(etdemmetaille),ngatifsilabasic_stringsurlaquellelamthode compare
estappliqueestpluspetitequelachanepasseenargument,soitentaille,soitausensdelordre
lexicographique,etpositifdanslecascontraire.
Exemple1412.Comparaisonsdechanesdecaractres
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
constchar*c1="bcderefb";
constchar*c2="bcdetab"; //c2 > c1
constchar*c3="bcderefas";//c3< c1
constchar*c4="bcde";
//c4 < c1
strings1=c1;
if(s1 < c2)cout << "c1 < c2" << endl;
elsecout << "c1 >=c2" << endl;
if(s1.compare(c3)>0)cout << "c1 > c3" << endl;
elsecout << "c1 <=c3" << endl;
if(s1.compare(0,string::npos,c1,4)
>0)
cout << "c1 > c4" << endl;
elsecout << "c1 <=c4" << endl;
return0;
}
Bienentendu,lesoprateursdecomparaisonclassiquessontgalementdfinisafindepermettredes
comparaisonssimplesentrechanedecaractres.Grcecesoprateurs,ilestpossibledemanipuler
248
Chapitre14.Lestypescomplmentaires
lesbasic_stringexactement commelesautrestypesordonnsdulangage. Plusieurssurchargede
cesoprateursonttdfiniesettravaillentaveclesdiffrentstypesdedonnesaveclesquelsilest
possiblepourunebasic_stringdesecomparer.Lemploidecesoprateursestnatureletneposepas
deproblmesparticuliers.
Note:ToutescescomparaisonssebasentsurlordrelexicographiquedulangageC.Autrement
dit, lescomparaisonsentrechanesdecaractresnetiennent pascomptedelalocaleet des
conventionsnationales.Ellessontdonctrsefficaces,maisnepourrontpastreutilisespour
comparerdeschanesdecaractreshumainementlisibles.Voustrouverezdeplusamplesren
seignementssurlamaniredeprendreencompteleslocalesdanslescomparaisonsdechanes
decaractresdansleChapitre16.
14.1.7.Recherchedansleschanes
Lesoprationsderecherchedansleschanesdecaractresconstituentunedesfonctionnalitsdes
chaneslespluscourantes.Ellesconstituentlaplupartdesoprationsdanalysedeschanes,etsont
souventlependantdelaconstructionetlaconcatnationdechanes.Laclassebasic_stringfournit
donctoutunensembledemthodespermettantdeffectuerdesrecherchesdecaractresoudesous
chanesdansunebasic_string.
Lesfonctionsderecherchesonttoutessurchargesafindepermettredespcifierlapositionpartir
delaquellelarecherchedoitcommencerdunepart,etlemotifdecaractrerechercher.Lepremier
paramtreindiquetoujoursquelestcemotif, quecesoituneautrebasic_string, unechanedeca
ractresCclassiqueouunsimplecaractre. Ledeuximeparamtreestlenumroducaractrede
labasic_stringsurlaquellelamthodederecherchesappliqueetpartirduquelleellecommence.
Cedeuximeparamtrepeuttreutilispoureffectuerplusieursrecherchessuccessives,enrepartant
deladernirepositiontrouvechaquefois.Lorsdunepremirerechercheoulorsdunerecherche
unique,ilnestpasncessairededonnerlavaleurdeceparamtre,carlesmthodesderechercheuti
lisentlavaleurpardfautquiconvient(soitledbutdelachane,soitlafin,selonlesensderecherche
utilisparlamthode).Lesparamtressuivantspermettentdedonnerdesinformationscomplmen
tairessurlemotifutiliserpourlarecherche.Ilnestutilisquelorsquelemotifestunechanede
caractresCclassique.Danscecas,ilesteneffetpossibledespcifierlalongueurdumotifdanscette
chane.
Lesdiffrentesfonctionsderecherchedisponiblessontprsentesdansletableausuivant:
Tableau141.Fonctionsderecherchedansleschanesdecaractres
Mthode
Description
find
Cettemthodepermetderechercherlasouschanecorrespondantau
motifpassenparamtredanslabasic_stringsurlaquelleelleest
applique.Elleretournelindicedelapremireoccurrencedecemotif
danslachanedecaractres,oulavaleur npos silemotifnyapparat
pas.
rfind
Cettemthodepermetdeffectuerunerecherchesimilairecelledela
mthode find,maisenparcourantlachanedecaractresensensinverse.
Notezbienquecenestpaslemotifquiestinversici,maislesensde
parcoursdelachane.Ainsi,lamthode rfind retournelindicedela
dernireoccurrencedumotifdanslachane,oulavaleur npos silemotif
napasttrouv.
249
Chapitre14.Lestypescomplmentaires
Mthode
Description
find_first_of
Cettemthodepermetderechercherlapremireoccurrencedundes
caractresprsentsdanslemotiffournienparamtre.Ilnesagitdonc
plusdunerecherchedechanedecaractres,maisdelarecherchedetous
lescaractresdunensembledonn.Lavaleurretourneestlindicedu
caractretrouv,oulavaleur npos siaucuncaractredumotifnest
dtectdanslachane.
find_last_of
find_first_not_of
Cettemthodetravailleenlogiqueinverseparrapportlamthode
find_first_of.Eneffet,ellerecherchelepremiercaractredela
basic_stringquinestpasdanslemotiffournienparamtre.Ellerenvoie
lindicedececaractre,ou npos siceluicinexistepas.
find_last_not_of
Cettemthodeeffectuelemmetravailquelamthode
find_first_not_of,maisenparcourantlachanedecaractressource
ensensinverse.Elledterminedonclindicedupremiercaractreen
partantdelafinquinesetrouvepasdanslemotiffournienparamtre.
Ellerenvoie npos siaucuncaractrenecorrespondcecritre.
Exemple1413.Recherchesdansleschanesdecaractres
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings="Bonjour tout
lemonde!";
//Recherchelemot"monde":
string::size_typepos=s.find("monde");
cout << pos << endl;
//Recherchelemot"tout"encommenantparlafin:
pos=s.rfind("tout");
cout << pos << endl;
//Dcomposelachaneenmots:
string::size_typedebut=s.find_first_not_of("\t\n");
while(debut!=string::npos)
{
//Recherchelafindumotsuivant:
pos=s.find_first_of("\t\n",debut);
//Affichelemot:
if(pos!=string::npos)
cout << s.substr(debut,posdebut)<< endl;
else
cout << s.substr(debut) << endl;
debut=s.find_first_not_of("\t\n",pos);
}
return0;
}
250
Chapitre14.Lestypescomplmentaires
Note:Toutescesfonctionsderechercheutilisent lordrelexicographiquedulangageCpour
effectuerleurtravail.Ellespeuventdoncnepasconvenirpoureffectuerdesrecherchesdansdes
chanesdecaractressaisiespardeshumains,carellesneprennentpasencomptelalocaleet
lesparamtresnationauxdelutilisateur.Laraisondecechoixestessentiellementlarecherche
delefficacitdanslabibliothquestandard. NousverronsdansleChapitre16lamanirede
procderpourprendreencomptelesparamtresnationauxauniveaudeschanesdecaractres.
14.1.8.Fonctionsdentre/sortiedeschanesde
caractres
Pourterminercetourdhorizondeschanesdecaractres,signalonsquelabibliothquestandardC++
fournitdesoprateurspermettantdeffectuerdescrituresetdeslecturessurlesfluxdentre/sortie.
Lesoprateurs <<et >>sontdoncsurchargspourlesbasic_string,etpermettentdemanipuler
cellescicommedestypesnormaux.Loprateur<<permetdenvoyerlecontenudelabasic_string
surlefluxdesortiestandard.Loprateur >>litlesdonnesdufluxdentrestandard,etlesaffecte
labasic_stringquilreoitenparamtre.Ilsarrtedsquilrencontrelecaractredefindefichier,
unespace,ouquelataillemaximaledesbasic_stringatatteinte(casimprobable):
#include <iostream>
#include <string>
usingnamespacestd;
intmain(void)
{
strings1,s2;
cin >> s1;
cin >> s2;
cout << "Premiermot:" << endl << s1 << endl;
cout << "Deuximemot:" << endl << s2 << endl;
return0;
}
Cependant,cesoprateurspeuventnepassavrersuffisants.Eneffet,lunedesprincipalesdifficults
danslesprogrammesquimanipulentdeschanesdecaractresestdelirelesdonnesquiproviennent
dunfluxdentreligneparligne. Lanotiondelignenestpastrsclaire, etdpendfortementde
lenvironnementdexcution.LabibliothquestandardC++suppose,quantelle,queleslignessont
dlimitesparuncaractrespcialservant demarqueurspcial. Gnralement, cecaractreestle
caractre \n,maisilestgalementpossibledutiliserdautressparateurs.
Poursimplifierlesoprationsdelecturedetextesconstitusdelignes,labibliothquefournitlafonc
tion getline.Cettefonctionprendenpremierparamtrelefluxdentresurlequelelledoitlirela
ligne,etlabasic_stringdanslaquelleelledoitstockercetteligneendeuximeparamtre.Letroisime
paramtrepermetdindiquerlecaractresparateurdeligne.Ceparamtreestfacultatif,carildispose
dunevaleurpardfautquicorrespondaucaractredefindeligneclassique\n.
Exemple1414.Lecturedelignessurlefluxdentre
#include <iostream>
#include <string>
251
Chapitre14.Lestypescomplmentaires
usingnamespacestd;
intmain(void)
{
strings1,s2;
getline(cin,s1);
getline(cin,s2);
cout << "Premireligne:"
cout << "Deuximeligne:"
return0;
}
14.2.Lestypesutilitaires
Labibliothquestandardutiliseeninterneuncertainnombredetypesdedonnesspcifiques,
es
sentiellementdansunbutdesimplicitetdefacilitdcriture.Cestypesserontengnralrarement
utilissparlesprogrammeurs, maiscertainesfonctionnalitsdelabibliothquestandardpeuventy
avoirrecours.Ilfautdoncconnatreleurexistenceetsavoirlesmanipulercorrectement.
14.2.1.Lespointeursauto
Laplupartdesvariablesdtruisentleurcontenulorsquellessontdtruitesellesmmes.Uneexception
notablececomportementestbienentenducelledespointeurs,quipardfinitionnecontiennentpas
euxmmesleursdonnesmaispluttunerfrencesurcellesci.Lorsquecesdonnessontalloues
dynamiquement,ilfautsystmatiquementpenserlesdtruiremanuellementlorsquonnenaplus
besoin. Celapeutconduiredesfuitesdemmoire(MemoryLeakenanglais)trsfacilement.
Sidetellesfuitesnesontpasgnantespourlesprocessusdontladuredevieesttrscourte,elles
peuventltreconsidrablementpluspourlesprocessusdestinsfonctionnerlongtemps,sicenest
enpermanence,surunemachine.
Enfait, dansuncertainnombredecas, lallocationdynamiquedemmoirenestutilisequepour
effectuerlocalementdesoprationssurunnombrearbitrairededonnesquinepeuttreconnuqu
lexcution. Cependant, ilestrelativementraredavoirconservercesdonnessurdelonguesp
riodes, et il est souvent souhaitablequecesdonnessoient dtruiteslorsquelafonctionqui lesa
allouessetermine.Autrementdit,ilfaudraitquelespointeursdtruisentautomatiquementlesdon
nesquilsrfrencentlorsquilssonteuxmmesdtruits.
LabibliothquestandardC++fournitceteffetuneclassedencapsulationdespointeurs,quipermet
dobtenircesfonctionnalits. Cetteclassesenommeauto_ptr, enraisondufait quesesinstances
sontutilisescommedespointeursdedonnesdontlaporteestlammequecelledesvariables
automatiques.Ladclarationdecetteclasseestralisecommesuitdanslentte memory :
template <classT >
classauto_ptr
{
public:
typedefTelement_type;
explicitauto_ptr(T*pointeur=0)throw();
auto_ptr(constauto_ptr&source)throw();
template <classU >
auto_ptr(constauto_ptr<U> &source)throw();
252
Chapitre14.Lestypescomplmentaires
~auto_ptr()throw();
auto_ptr&operator=(constauto_ptr&source)throw();
template <classU >
auto_ptr&operator=(constauto_ptr
<U> &source)throw();
T&operator*()constthrow();
T*operator>()constthrow();
T*get()constthrow();
T*release()constthrow();
};
Cetteclassepermetdeconstruireunobjetcontrlantunpointeursurunautreobjetalloudynami
quementavecloprateur new.Lorsquilestdtruit,lobjetrfrencestautomatiquementdtruitpar
unappelloprateur delete.Cetteclasseutilisedoncunesmantiquedepropritstrictedelobjet
contenu,puisquelepointeurainsicontrlnedoittredtruitquuneseulefois.
Celaimpliqueplusieursremarques. Premirement, il yancessairement untransfert deproprit
dupointeurencapsullorsdesoprationsdecopieetdaffectation.Deuximement,touteopration
susceptibledeprovoquerlapertedupointeurencapsulprovoquesadestructionautomatiquement.
Cestnotammentlecaslorsquuneaffectationduneautrevaleurestfaitesurunauto_ptrcontenant
djunpointeurvalide.Enfin,ilnefautjamaisdtruiresoimmelobjetpointunefoisquelona
affectunpointeursurceluiciunauto_ptr.
Il est trssimpledutiliserlespointeursautomatiques. Eneffet, il suffit delesinitialiserleur
constructionaveclavaleurdupointeursurlobjetalloudynamiquement.
Dslors, ilestpossible
dutiliserlauto_ptrcommelepointeuroriginal,puisquildfinitlesoprateurs*et >.
Lesauto_ptrsontsouventutilissentantquevariableautomatiquedanslessectionsdecodesuscep
tibledelancerdesexceptions,puisquelaremontedesexceptionsdtruitlesvariablesautomatiques.
Ilnestdoncplusncessairedetraitercesexceptionsetdedtruiremanuellementlesobjetsallous
dynamiquementavantderelancerlexception.
Exemple1415.Utilisationdespointeursautomatiques
#include <iostream>
#include <memory>
usingnamespacestd;
classA
{
public:
A()
{
cout << "Constructeur" << endl;
}
~A()
{
cout << "Destructeur" << endl;
}
};
//Fonctionsusceptibledelanceruneexception:
253
Chapitre14.Lestypescomplmentaires
voidf()
//Allouedynamiquementunobjet:
auto_ptr<A> p(newA);
//Lanceuneexception,enlaissantaupointeur
//automatiquelesoindedtruirelobjetallou:
throw2;
}
intmain(void)
{
try
{
f();
}
catch(...)
{
}
return0;
}
Note:Onprendrabiengardeaufaitquelacopiedunauto_ptrdansunautreeffectueuntrans
fert deproprit. Celapeut provoquerdessurprises, notamment si lonutilisedesparamtres
defonctionsdetypeauto_ptr(choseexpressment dconseille). Eneffet, il yaurasystma
tiquementtransfertdepropritdelobjetlorsdelappel delafonction,etcestdonclafonction
appelequi enauralaresponsabilit.Si ellenefaitaucuntraitementspcial,lobjetseradtruit
avecleparamtredelafonction,lorsquelexcutionduprogrammeensortira!Inutilededireque
lafonctionappelanterisquedavoirdespetitsproblmes...Pourvitercegenredeproblmes,il
estpluttconseilldepasserlesauto_ptrparrfrenceconstantepluttqueparvaleurdansles
appelsdefonctions.
Unautrepigeclassiqueest dinitialiserunauto_ptravecladressedunobjet qui napast
alloudynamiquement.Ilestfaciledefairecetteconfusion,caronnepeutaprioripasdiresiun
pointeurpointesurunobjetalloudynamiquementounon.Quoiquilensoit,sivousfaitescette
erreur,unappel delete serafaitavecunparamtreincorrectlorsdeladestructiondupointeur
automatiqueetleprogrammeplantera.
Enfin, sachezquelespointeursautomatiquesnutilisent queloprateur delete pourdtruire
lesobjetsquilsencapsulent, jamaisloprateur delete[] . Parconsquent, lespointeursau
tomatiquesnedevront jamaistreinitialissavecdespointeursobtenuslorsduneallocation
dynamiqueavecloprateur new[] ouaveclafonction malloc delabibliothqueC.
Ilestpossibledercuprerlavaleurdupointeurprisenchargeparunpointeurautomatiquesimple
ment,grcelamthode get.Celapermetdetravailleraveclepointeuroriginal,cependant,ilnefaut
jamaisoublierquecestlepointeurautomatiquequienatoujourslaproprit.Ilnefautdoncjamais
appeler delete surlepointeurobtenu.
Enrevanche,silonveutsortirlepointeurdunauto_ptr,etforcerceluicienabandonnerlapro
prit,onpeututiliserlamthode release.Cettemthoderenvoieelleaussilepointeursurlobjet
quelauto_ptrcontenait,maislibregalementlarfrencesurlobjetpointauseindelauto_ptr.
Ainsi,ladestructiondupointeurautomatiqueneprovoqueraplusladestructiondelobjetpointetil
faudranouveauprendreenchargecettedestructionsoimme.
254
Chapitre14.Lestypescomplmentaires
Exemple1416.Sortiedunpointeurdunauto_ptr
#include <iostream>
#include <memory>
usingnamespacestd;
classA
{
public:
A()
{
cout << "Constructeur" << endl;
}
~A()
{
cout << "Destructeur" << endl;
}
};
A*f(void)
{
cout << "Construciondelobjet"<< endl;
auto_ptr<A> p(newA);
cout << "Extractiondupointeur"<< endl;
returnp.release();
}
intmain(void)
{
A*pA=f();
cout << "Destructiondelobjet"<< endl;
deletepA;
return0;
}
14.2.2.Lespaires
Outrelespointeursautomatiques,labibliothquestandardC++dfinituneautreclasseutilitairequi
permet quant elledestockeruncoupledevaleursdansunmmeobjet.
Cetteclasse, laclasse
template pair, est enparticuliertrsutilisedanslimplmentationdecertainsconteneursdela
bibliothque.
Ladclarationdelaclasse template pairestlasuivantedanslentte
utility :
template <classT1,classT2>
structpair
{
typedefT1first_type;
typedefT2second_type;
T1first;
T2second;
pair();
255
Chapitre14.Lestypescomplmentaires
pair(constT1&,constT2&);
template <classU1,classU2>
pair(constpair<U1,U2> &);
};
template <classT1,classT2>
booloperator==(constpair<T1,T2> &,constpair<T1,T2> &);
template <classT1,classT2>
booloperator<(constpair<T1,T2> &,constpair<T1,T2> &);
template <classT1,classT2>
pair<T1,T2> make_pair(constT1&,constT2&);
Commecettedclarationlemontre,lutilisationdelaclassepairestextrmementsimple.Laconstruc
tiondunepairesefaitsoitenfournissantlecoupledevaleursdevanttrestockdanslapaire,soiten
appelantlafonction make_pair.Larcuprationdesdeuxcomposantesdunepairesefaitsimple
mentenaccdantauxdonnesmembrespubliques first et second .
Exemple1417.Utilisationdespaires
#include <iostream>
#include <utility>
usingnamespacestd;
intmain(void)
{
//Construitunepaireassociantunentier
//unflottant:
pair<int,double> p1(5,7.38),p2;
//Initialisep2avecmake_pair:
p2=make_pair(9,3.14);
//Affichelesdeuxpaires:
cout << "p1=(" << p1.first << ","
<< p1.second << ")" << endl;
cout << "p2=(" << p2.first << ","
<< p2.second << ")" << endl;
return0;
}
256
Chapitre14.Lestypescomplmentaires
14.3.Lestypesnumriques
Enplusdestypesdintrtgnralvusdanslessectionsprcdentes,labibliothquestandardfournit
destypesdedonnesplusspcialissdanslescalculsnumriquesoumathmatiques.Cestypesde
donnespermettentdeffectuerdescalculssurlesnombrescomplexes,ainsiquedescalculsparallles
surdestableauxdevaleurs.
14.3.1.Lescomplexes
LestypesdebasedulangageC++fournissentuneapproximationrelativementfiabledesdiffrents
domainesdenombresmathmatiques. Parexemple, letypeintpermetdereprsenteruneplagede
valeurslimitedesentiersrelatifs, maissuffisammentlargetoutefoispourpermettredeffectuerla
plupart descalculsintervenant danslavierelle. Demme, lestypesdesnombresvirguleflot
tantefournissentuneapproximationrelativementsatisfaisantedesnombresrelsdesmathmatiques.
Lapproximationcettefoisportenonseulementsurlaplagedevaleuraccessible,maisgalementsur
laprcisiondesnombres.
Note:Onprendrabienconsciencedufaitquelestypesdulangagenereprsententeffective
mentquedesapproximations,carlesordinateurssontdesmachineslimitesenmmoireeten
capacitdereprsentationdumonderel. Il faut donctoujourspenserauxventuelscasde
dbordementseterreursdereprsentationdesnombres,surtoutencequi concernelesnom
bresrels.Lesbogueslesplusgraves(entermedepertesmatriellesouhumaines)sontsouvent
dsdetelsdbordements,quisontinhrentsauxtechniquesutilisesparlinformatique(mme
avecdeslangagesplussrsqueleC++).
Ilexisteenmathmatiquesunautretypedenombres,quinontpasdereprsentationphysiqueim
mdiatepourlecommundesmortels, maisquipermettentsouventdesimplifierbeaucoupcertains
calculs:lesnombrescomplexes.Cesnombrestendenteneffetledomainedesnombresaccessibles
etpermettentdepoursuivrelescalculsquintaientpasralisablesaveclesnombresrelsseulement,
ensaffranchissantdescontraintesimposessurlessolutionsdesquationsalgbriques.Lesnombres
complexessontdoncdunetrsgrandeutilitdanstoutelalgbre,etenparticulierdanslescalculs
matricielsoilsprennentuneplaceprdominante.Lesnombrescomplexespermettentgalementde
simplifiersrieusementlescalculstrigonomtriques,lescalculsdesignauxenlectricitetlescal
culsenmcaniquequantique.Leplusintressantaveccesnombresestsansdoutelefaitquemme
silesrsultatsintermdiairesquelontrouveaveceuxnontpasdesignificationrelle,lesrsultats
finaux,eux,peuventenavoiruneetnauraientpasttrouvsaussifacilementenconservanttoutes
lescontraintesimposesparlesnombresrels.
Afindesimplifierlaviedesprogrammeursqui ont besoindemanipulerdesnombrescomplexes,
labibliothquestandardC++dfinitlaclasse template complex,quipermetdelesreprsenteret
deffectuerlesprincipalesoprationsmathmatiquesdessus.Silutilisationdelaclassecomplexen
soi neposeaucunproblmeparticulier, il peut treutilededonnerunedescriptionsommairede
cequest unnombrecomplexepourlesnophytesenmathmatiques.
Toutefois, cettedescription
nestpasdestineauxpersonnesnayantaucuneconnaissanceenmathmatiques(sitantestquun
programmeurpuissetredanscecas...). Si vousnelacomprenezpas, cest sansdoutequevous
navezaucunement besoindesnombrescomplexeset vouspouvezdoncpassercettesectionsans
crainte.
257
Chapitre14.Lestypescomplmentaires
14.3.1.1.Dfinitionetprincipalespropritsdesnombrescomplexes
Ilnestpascompliqudesereprsentercequesignifieunnombrerelpuisquonlesutilisecouram
mentdanslaviecourante. Lamthodelaplussimpleestdimaginerunerglegradueochaque
positionestdonneparunnombrerelparrapportlorigine.Cenombreindiquelenombredefois
quelunitdedistancedoittrerptedepuisloriginepourarrivercetteposition.
Poursereprsenterlavaleurdunnombrecomplexe,ilfaututiliserunedimensionsupplmentaire.
Enfait,toutnombrecomplexepeuttreexprimavecdeuxvaleursrelles:lapartierelleducom
plexe,etsapartieimaginaire.Plusieursnotationsexistentpourreprsenterlesnombrescomplexes
partirdecesdeuxparties.Lapluscouranteestdedonnerlapartierelleetlapartieimaginaireentre
parenthses,sparesparunevirgule:
(relle,imaginaire)
Lexemplesuivantvousprsentequelquesnombrescomplexes:
7.56
3i
5+7i
Vousconstaterezquelesnombresrelspeuventparfaitementtrereprsentsparlesnombrescom
plexes,puisquilsuffitsimplementdutiliserunepartieimaginairenulle.
Lesoprationsalgbriquesclassiquesonttdfiniessurlesnombrescomplexes. Lesadditionset
soustractionssefontmembremembre,partierelleavecpartierelleetpartieimaginaireavecpartie
imaginaire.Enrevanche,lamultiplicationestunpeupluscomplexe,carellesebasesurlaproprit
fondamentalequelecarrdelunitdelapartieimaginairevaut 1.Autrementdit,lesymbole i de
i2 =1. Ilsagitenquelque
lanotationprcdentedisposedelapropritfondamentalesuivante:
sorteduneracinecarrede 1 (laracinecarredesnombresngatifsnayantpasdesens,puisquun
carrestnormalementtoujourspositif, oncomprendlaqualificationdimaginairedesnombres
complexes).partirdecettergledebase,etenconservantlesrglesdassociativitdesoprateurs,
onpeutdfinirleproduitdedeuxnombrescomplexescommesuit:
(a,b)*(c,d)=(acbd,ad+bc)
),b/(a2 +b
))
partirdelinverse,ilestsimpledecalculerunedivisionquelconque.
Commeillatditplushaut,lesnombrescomplexespeuventtrereprsentsenutilisantunedimen
sionsupplmentaire.Ainsi,siondfinitunrepredansleplan,dontlaxedesabscissesestassoci
lapartierelledesnombrescomplexesetlaxedesordonneslapartieimaginaire,toutnombre
complexeestassociunpointduplan.Onappellealorsceplanleplancomplexe.Ladfinitiondes
complexesdonneicicorresponddoncunsystmedecoordonnescartsiennesduplancomplexe,
etchaquenombrecomplexedisposedesesproprescoordonnes.
258
Chapitre14.Lestypescomplmentaires
Enmathmatiques,ilestgalementcourantdutiliserunautresystmedecoordonnes:lesystme
decoordonnespolaires.Danscesystme,chaquepointduplanestidentifinonplusparlescoor
donnesdesesprojectionsorthogonalessurlesaxesdurepre,maisparsadistancelorigineetpar
langlequeladroitequirejointlorigineaupointfaitaveclaxedesabscisses.Cesdeuxnombressont
courammentnotsrespectivementavecleslettresgrecquesrhoettheta.Ladnominationdecoordon
nespolairesprovientdufaitqueloriginedureprejouelerledunpleparrapportauquelonsitue
lepointdansleplan.
Ilestdoncvidentquelesnombrescomplexespeuventgalementtrereprsentsparleurscoor
donnespolaires.Onappellegnralementladistanceloriginelanormedunombrecomplexe,et
langlequilfaitaveclaxedesabscissessonargument.Faitesbienattentionceterme,ilnerepr
sentepasunargumentdunefonctionouquoiquecesoitquiserapportelaprogrammation.
Laplupartdesfonctionsmathmatiquesclassiquesonttdfiniessurlesnombrescomplexes,par
foisenrestreignantleurdomainedevalidit.Ainsi,ilestpossibledecalculerunsinus,uncosinus,
uneexponentielle,etc.pourlesnombrescomplexes.Ilestbienentenduhorsdequestiondedfinir
rigoureusement,nimmedeprsentersuccinctementcesfonctionsdanscedocument.Cependant,il
estbondesavoirquonnepeutpasdfinirunerelationdordresurlesnombrescomplexes.Autrement
dit,onnepeutpasfairedautrecomparaisonquelgalitentredeuxnombrescomplexes(essayezde
comparerlesnombrescomplexessitussuruncerclecentrloriginedansleplancomplexepour
vousenrendrecompte).
14.3.1.2.Laclassecomplex
Laclasse template complexestdfiniedanslentte complex delabibliothquestandard.Cette
classepeut treinstanciepourlunquelconquedestroistypesdenombrevirguleflottantedu
langage:float,doubleoulongdouble.Ellepermetdeffectuerlesprincipalesoprationsdfiniessur
lesnombrescomplexes,commelesadditions,soustractions,multiplications,division,maisgalement
desoprationsspcifiquesauxnombrescomplexes,commeladterminationdeleurargumentoude
leurnorme.Enfin,lentte complex contientdessurchargesdesfonctionsmathmatiquesstandards,
tellesquelesfonctionstrigonomtriques,laracinecarre,lespuissancesetexponentielles,ainsique
leslogarithmes(dfinissurleplancomplexeauquellaxedesabscissesngativesatt).
Laconstructionduncomplexeneposeaucunproblmeensoi.
Laclassecomplexdisposedun
constructeurpardfaut,dunconstructeurdecopieetdunconstructeurprenantenparamtrelapartie
relleetlapartieimaginairedunombre:
#include <iostream>
#include <complex>
usingnamespacestd;
intmain(void)
{
complex<double> c(2,3);
cout << c << endl;
return0;
}
Lexempleprcdentprsentegalementloprateurdesortiesurlesfluxstandards,quiformateun
nombrecomplexeenutilisantlanotation (rel,imaginaire).Ilexistegalementunesurcharge
deloprateurdentrepourlefluxdentre:
259
Chapitre14.Lestypescomplmentaires
#include <iostream>
#include <complex>
usingnamespacestd;
intmain(void)
{
complex<double> c;
cin >> c;
cout << "Vousavezsaisi:"
return0;
}
Note:Malheureusement,cettenotationposedesproblmesaveclalocalefranaise,puisque
nousutilisonsdesvirgulespoursparerlapartieentiredelapartiedcimaledesnombres
virgules.Lorsquelundesdeuxnombresflottantsestunentier,il estimpossiblededterminer
osetrouvelavirgulesparant lapartieentiredelapartieimaginairedunombrecomplexe.
Unepremiresolutionestdemodifierleformatagedesnombresrelspourqueleschiffresaprs
lavirgulesoient toujoursaffichs, mmesilssont nuls. Cependant, il faut galement imposer
quelessaisiesdesnombressoientgalementtoujourseffectusavecdesnombresvirgules,
cequi estsujeterreuretinvrifiable.Il estdoncrecommanddenutiliserquelalocaledela
bibliothqueClorsquonfaitunprogrammeutilisantlesnombrescomplexes.
Ilnexistepasdeconstructeurpermettantdecrerunnombrecomplexepartirdesescoordonnes
polaires. Enrevanche, lafonction polar permetdenconstruireun. Cettefonctionprendenpara
mtrelanormeducomplexeconstruireainsiquesonargument.Ellerenvoielenombrecomplexe
nouvellementconstruit.
Lapartieimaginaireetlapartierelledunnombrecomplexepeuventtrercuprestoutinstant
laidedesmthodes real et imag delaclasse template complex.Ilestgalementpossibledutiliser
lesfonctions templaterealet imag,quiprennenttoutesdeuxlenombrecomplexedontilfautcal
culerlapartierelleetlapartieimaginaire.Demme,lanormedunnombrecomplexeestretourne
parlafonction abs,etsonargumentpeuttreobtenuaveclafonction arg.
Bienentendu,lesoprationsclassiquessurlescomplexessefontdirectement,commesilsagissait
duntypeprdfinidulangage:
#include <iostream>
#include <complex>
usingnamespacestd;
intmain(void)
{
complex<double> c1(2.23,3.56);
complex<double> c2(5,5);
complex<double> c=c1+c2;
c=c/(c1c2);
cout << c << endl;
return0;
}
260
Chapitre14.Lestypescomplmentaires
Lesfonctionsspcifiquespermettantdemanipulerlescomplexesetdeleurappliquerlesoprations
quileurssontpropressontrcapitulesdansletableausuivant:
Tableau142.Fonctionsspcifiquesauxcomplexes
Fonction
Description
real
Retournelapartierelledunombrecomplexe.
imag
Retournelapartieimaginairedunombrecomplexe.
abs
Retournelanormedunombrenombrecomplexe,cestdiresadistance
lorigine.
arg
Retournelargumentdunombrecomplexe.
norm
Retournelecarrdelanormedunombrecomplexe.Attention,cette
fonctionportemalsonnom,puisquelavraienormeestretourneparla
surchargedelafonction abs pourlesnombrescomplexes.Cette
incohrenceprovientdelinterprtationdiffrentedecelledesFranais
quefontlesAnglosaxonsdelanotiondenorme.
conj
Retournelenombrecomplexeconjugudunombrecomplexefournien
argument.Lenombreconjugudunnombrecomplexeestsonsymtrique
parrapportlaxedesabscissesdansleplancomplexe,cestdirequil
disposedelammepartierelle,maisquesapartieimaginaireest
opposecelledunombrecomplexeoriginal(celarevientgalement
direquelargumentduconjuguestlopposdelargumentducomplexe
original).Leproduitdunnombrecomplexeetdesonconjugudonnele
carrdesanorme.
polar
Permetdeconstruireunnombrecomplexepartirdesescoordonnes
polaires.
Exemple1418.Manipulationdesnombrescomplexes
#include <iostream>
#include <complex>
usingnamespacestd;
intmain(void)
{
//Creunnombrecomplexe:
complex<double> c(2,3);
//Dterminesonargumentetsanorme:
doubleArg=arg(c);
doubleNorm=abs(c);
//Construitlenombrecomplexeconjugu:
complex<double> co=polar(Norm,Arg);
//Affichelecarrdelanormeduconjugu:
cout << norm(co) << endl;
//Calculelecarrcecettenormeparleproduit
//ducomplexeetdesonconjugu:
cout << real(c*conj(c)) << endl;
return0;
}
261
Chapitre14.Lestypescomplmentaires
14.3.2.Lestableauxdevaleurs
CommeillatexpliqudansleChapitre1,lesprogrammesclassiquesfonctionnenttoujourssurle
mmeprincipe:ilstravaillentsurdesdonnesquilsreoiventenentreetproduisentdesrsultatsen
sortie.Cemodedefonctionnementconvientdanslagrandemajoritdescas,etenfaitlesprogrammes
quelonappellecourammentlesfiltresensontunedesapplicationsprincipales.Unfiltrenest
riendautrequunprogrammepermettant,commesonnomlindique,defiltrerlesdonnesreuesen
entreselonuncritreparticulieretdenefournirensortiequelesdonnesquisatisfontcecritre.
Certainsfiltresplusvoluspeuventmmemodifierlesdonneslavoleoulestraduiredansun
autreformat. Lesfiltressonttrssouventutilissaveclesmcanismesderedirectiondessystmes
quilessupportentafindexcuterdestraitementscomplexessurlesfluxdedonnespartirdefiltres
simples,eninjectantlesrsultatsdesunsdanslefluxdentredesautres.
Cependant,cemodleaunelimitepratiqueentermedeperformances,carilncessiteuntraitement
squentiel desdonnes. Lavitessedexcutiondunprogrammeconuseloncemodleest
donc
directementlilavitessedexcutiondesinstructions,donclavitesseduprocesseurdelamachine
utilise.Lorsquunhautniveaudeperformancedoittreatteint,plusieurssolutionssontdisponibles.
Danslapratique,ondistinguetroissolutionsclassiques.
Lapremiresolutionconsistesimplement,pouraugmenterlapuissancedunemachine,augmenter
celleduprocesseur.Celasetraduitsouventparuneaugmentationdelafrquencedeceprocesseur,
techniquequetoutlemondeconnat. Lesavantagesdecettesolutionsontvidents:touslespro
grammesbnficientdirectementdelaugmentationdelapuissanceduprocesseuretnontpastre
modifis.Enrevanche,cettetechniqueatteindraunjourouunautreseslimitesentermesdecotsde
fabricationetdemoyenstechniquesmettreenoeuvrepourproduirelesprocesseurs.
Ladeuximesolutionestdaugmenterlenombredeprocesseursdelamachine.Cettesolutionesttrs
simple,maissupposequelesprogrammessoientcapablesdeffectuerplusieurscalculsindpendants
simultanment.Enparticulier,lestraitementseffectuerdoiventtresuffisammentindpendantset
nepasavoirattendrelesdonnesproduitesparlesautresafindepouvoirrellementtreex
cutsenparallle. Onquittedonclemodlesquentiel, pourentrerdansunmodledetraitement
ochaqueprocesseurtravailleenparallle(modleMIMD,abrviationdelanglaisMultiple
InstructionMultipleData).Cettetechniqueestgalementsouventappeleleparalllismedetraite
ment.Malheureusement,pourununiqueprocessuspurementsquentiel,cettetechniqueneconvient
pas,puisquedetoutesfaons,lesoprationsexcuterneleserontqueparunseulprocesseur.
Enfin,ilexisteunetechniquemixte,quiconsisteparallliserlesdonnes.Lesmmesoprationsdun
programmesquentielsontalorsexcutessurungrandnombrededonnessimilaires.Lesdonnes
sontdonctraitesparblocs,parununiquealgorithme:ilsagitduparalllismededonnes(SIMD
enanglais,abrviationdeSingleInstructionMultipleData).Cettesolutionestcellemiseenoeuvre
danslesprocesseursmodernesquidisposentdejeuxdinstructionsspcialisespermettantdeffectuer
descalculssurplusieursdonnessimultanment (MMX, 3DNowet SSEpourlesprocesseursde
typex86parexemple).Bienentendu,cettetechniquesupposequeleprogrammeaiteffectivement
traiterdesdonnessemblablesdemaniresimilaire. Cettecontraintepeutparatretrsforte, mais,
enpratique,lessituationslesplusconsommatricesderessourcessontjustementcellesquincessite
larptitiondunmmecalcul surplusieursdonnes. Onciteraparexempletouslesalgorithmes
detraitementdedonnesmultimdia,dontlesalgorithmesdecompression,detransformationetde
combinaison.
Silaugmentationdesperformancesdesprocesseursapporteungaindirectementobservablesurtous
lesprogrammes, cenestpaslecaspourlestechniquesdeparalllisation. Leparalllismedetrai
tement est gnralement accessibleauniveausystme, parlintermdiairedumultitcheet dela
programmationmultithreade. Il faut donccrirelesprogrammesdetellesortebnficierdece
paralllismedetraitement,laidedesfonctionsspcifiqueausystmedexploitation.Demme,le
paralllismededonnesncessiteladfinitiondetypesdedonnescomplexes,capablesdereprsen
262
Chapitre14.Lestypescomplmentaires
terlesblocsdedonnessurlesquelsleprogrammedoittravailler.
Cesblocsdedonnessontcou
rammentgrscommedesvecteursoudesmatrices,cestdire,engnral,commedestableauxde
nombres.Leprogrammedoitdoncutilisercestypesspcifiquespouraccdertouteslesressources
delamachine.Celancessiteunsupportdelapartdulangagedeprogrammation.
Chaqueenvironnementdedveloppementestsusceptibledefournirlestypesdedonnespermettant
deffectuerdestraitementsSIMD.Cependant,cestypesdpendentdelenvironnementutiliseten
coreplusdelaplateformeutilise.LabibliothquestandardC++permetdvitercescueils,carelle
dfinituntypededonnepermettantdetraiterdestableauxunidimensionnelsdobjets,enassurant
quelesmcanismesdoptimisationpropreauxplatesformesmatriellesetauxcompilateursseront
effectivementutiliss:lesvalarray.
14.3.2.1.Fonctionnalitsdebasedesvalarray
Laclassevalarrayestuneclasse template capabledestockeruntableaudevaleursdesontype
template.Ilestpossibledelinstancierpourtouslestypesdedonnespourlesquelslesoprations
dfiniessurlaclassevalarraysontellesmmesdfinies.LabibliothquestandardC++garantitque
laclassevalarrayestcritedetellesortequetouslesmcanismesdoptimisationdescompilateurs
pourronttreappliqussurelle,afindobtenirdesperformancesoptimales.Deplus,chaqueimpl
mentationestlibredutiliserlespossibilitsdecalculparallledisponiblesurchaqueplateforme,du
moinspourlestypespourlesquelscesfonctionnalitssontprsentes.Parexemple,laclassevalarray
instanciepourletypefloatpeututiliserlesinstructionsspcifiquesdecalculsurlesnombresflottants
duprocesseursiellessontdisponibles.Toutefois,lanormenimposeaucunecontrainteceniveau,
etlamaniredontlaclassevalarrayestimplmenteresteladiscrtiondechaquefournisseur.
Laclassevalarrayfournit touteslesfonctionnalitsncessaireslaconstructiondestableauxde
valeurs,leurinitialisation,ainsiquleurmanipulation.Elleestdclarecommesuitdanslentte
valarray :
//Dclarationdesclassesdeslectiondesoustableau:
classslice;
classgslice;
//Dclarationdelaclassevalarray:
template <classT >
classvalarray
{
public:
//Typesdesdonnes:
typedefTvalue_type;
//Constructeursetdestructeurs:
valarray();
explicitvalarray(size_ttaille);
valarray(constT&valeur,size_ttaille);
valarray(constT*tableau,size_ttaille);
valarray(constvalarray&source);
valarray(constmask_array
<T> &source);
valarray(constindirect_array
<T> &source);
valarray(constslice_array
<T> &source);
valarray(constgslice_array
<T> &source);
~valarray();
//Oprateursdaffectation:
valarray<T> &operator=(constT&valeur);
valarray<T> &operator=(constvalarray
<T> &source);
263
Chapitre14.Lestypescomplmentaires
valarray<T>
valarray<T>
valarray<T>
valarray<T>
&operator=(constmask_array
<T> &source);
&operator=(constindirect_array
<T> &source);
&operator=(constslice_array
<T> &source);
&operator=(constgslice_array
<T> &source);
//Oprateursdaccsauxlments:
Toperator[](size_tindice)const;
T&operator[](size_tindice);
//Oprateursdeslectiondesousensembledutableau:
valarray<T>
operator[](constvalarray<bool> &masque)const;
mask_array<T>
operator[](constvalarray<bool> &masque);
valarray<T>
operator[](constvalarray<size_t> &indices)const;
indirect_array<T> operator[](constvalarray
<size_t> &indices);
valarray<T>
operator[](sliceselecteur)const;
slice_array<T>
operator[](sliceselecteur);
valarray<T>
operator[](constgslice&selecteur)const;
gslice_array<T>
operator[](constgslice&selecteur);
//Oprateursunaires:
valarray<T> operator+()const;
valarray<T> operator()const;
valarray<T> operator~()const;
valarray<T> operator!()const;
//Oprateursdaffectationcompose:
valarray<T> operator*=(constT&valeur);
valarray<T> operator*=(constvalaray
<T> &tableau);
valarray<T> operator/=(constT&valeur);
valarray<T> operator/=(constvalaray
<T> &tableau);
valarray<T> operator%=(constT&valeur);
valarray<T> operator%=(constvalaray
<T> &tableau);
valarray<T> operator+=(constT&valeur);
valarray<T> operator+=(constvalaray
<T> &tableau);
valarray<T> operator=(constT&valeur);
valarray<T> operator=(constvalaray
<T> &tableau);
valarray<T> operator^=(constT&valeur);
valarray<T> operator^=(constvalaray
<T> &tableau);
valarray<T> operator&=(constT&valeur);
valarray<T> operator&=(constvalaray
<T> &tableau);
valarray<T> operator|=(constT&valeur);
valarray<T> operator|=(constvalaray
<T> &tableau);
valarray<T> operator<<=(constT&valeur);
valarray<T> operator<<=(constvalaray<T> &tableau);
valarray<T> operator>>=(constT&valeur);
valarray<T> operator>>=(constvalaray<T> &tableau);
//Oprationsspcifiques:
size_tsize()const;
Tsum()const;
Tmin()const;
Tmax()const;
valarray<T> shift(int)const;
valarray<T> cshift(int)const;
valarray<T> apply(Tfonction(T))const;
valarray<T> apply(Tfonction(constT&))const;
voidresize(size_ttaille,Tinitial=T());
264
Chapitre14.Lestypescomplmentaires
};
Nousverronsdanslasectionsuivantelasignificationdestypesslice,gslice,slice_array,gslice_array,
mask_arrayetindirect_array.
Ilexisteplusieursconstructeurspermettantdecreretdinitialiseruntableaudevaleurs.Leconstruc
teurpardfautinitialiseuntableaudevaleurvide. Lesautresconstructeurspermettentdinitialiser
letableaudevaleurpartirdunevaleurdinitialisationpourtousleslmentsduvalarray,oudun
autretableaucontenantlesdonnesaffecterauxlmentsduvalarray:
//Construitunvalarraydedoubles:
valarray<double> v1;
//Initialiseunvalarraydedoublesexplicitement:
doublevaleurs[]={1.2,3.14,2.78,1.414,1.732};
valarray<double> v2(valeurs,
sizeof(valeurs)/sizeof(double));
//Construitunvalarrayde10entiersinitialiss3:
valarray<int> v3(3,10);
Vouspouvezconstaterqueledeuximeargumentdesconstructeursquipermettentdinitialiserles
valarrayprennentunargumentdetypesize_t,quiindiquelatailleduvalarray.Unefoisunvalarray
construit,ilestpossibledeleredimensionnerlaidedelamthode resize.Cettemthodeprenden
premierparamtrelanouvelletailleduvalarrayetlavaleuraffecterauxnouveauxlmentsdansle
casdunagrandissement.Lavaleurpardfautestcellefournieparleconstructeurpardfautdutype
desdonnescontenuesdanslevalarray. Lataillecourantedunvalarraypeuttrercupretout
momentgrcelamthode size.
Exemple1419.Modificationdelatailledunvalarray
#include <iostream>
#include <valarray>
usingnamespacestd;
intmain(void)
{
//Crationdunvalarray:
valarray<double> v;
cout << v.size() << endl;
//Redimensionnementduvalarray:
v.resize(5,3.14);
cout << v.size() << endl;
return0;
}
Touteslesoprationsclassiquesdesmathmatiquespeuventtreappliquessurunvalarraypourvu
quellespuissentltregalementsurletypedesdonnescontenuesparcetableau.Ladfinitionde
cesoprationsesttrssimple:loprationdutypedebaseestappliquesimplementchaquelment
contenudansletableaudevaleurs.
265
Chapitre14.Lestypescomplmentaires
Labibliothquestandarddfinitgalementlesoprateursbinairesncessairespoureffectuerlesop
rationsbinairessurchaquelmentdesvalarray.Enfait,cesoprateurssontclasssendeuxcatgo
ries,selonlanaturedeleursarguments.Lesoprateursdelapremirecatgoriepermettentdeffectuer
uneoprationentredeuxvalarraydemmedimension,
enappliquant cetteoprationmembre
membre. Ilsagitdoncrellementduneoprationvectorielledanscecas.
Enrevanche, lesopra
teursdeladeuximecatgorieappliquentloprationavecunemmeetuniquevaleurpourchaque
donnestockedanslevalarray.
Exemple1420.Oprationssurlesvalarray
#include <iostream>
#include <valarray>
usingnamespacestd;
voidaffiche(constvalarray
<double> &v)
{
size_ti;
for(i=0;i <v.size();++i)
cout << v[i] << "";
cout << endl;
}
intmain(void)
{
//Construitdeuxvalarraydedoubles:
doublev1[]={1.1,2.2,3.3};
doublev2[]={5.3,4.4,3.5};
valarray<double> vect1(v1,3);
valarray<double> vect2(v2,3);
valarray<double> res(3);
//Effectueunesommemembremembre:
res=vect1+vect2;
affiche(res);
//Calculelesinusdesmembresdupremiervalarray:
res=sin(vect1);
affiche(res);
return0;
}
Parmilesoprateursbinairesquelonpeutappliquerunvalarray,ontrouvebienentendulesop
rateursdecomparaison.Cesoprateurs,contrairementauxoprateursdecomparaisonhabituels,ne
renvoientpasunboolen,maispluttunautretableaudeboolens.Eneffet,lacomparaisondedeux
valarrayapourrsultat levalarraydesrsultatsdescomparaisonsmembresmembresdesdeux
valarray.
Laclassevalarraydisposedemthodespermettantdeffectuerdiversesoprationsspcifiquesaux
tableauxdevaleurs.Lamthode sum permetdobtenirlasommedetouteslesvaleursstockesdansle
tableaudevaleur.Lesmthodesshift et cshift permettent,quantelles,deconstruireunnouveau
valarraydontleslmentssontleslmentsduvalarrayauquellamthodeestapplique,dcalsou
permutscirculairement duncertainnombredepositions. Lenombrededplacementseffectus
estpassenparamtrecesdeuxfonctions, lesvaleurspositivesentranantdesdplacementsvers
lagaucheet lesvaleursngativesdesdplacementsversladroite. Danslecasdesdcalagesles
nouveauxlmentsintroduitspourremplacerceuxquinontpaseuxmmesderemplaantprennent
lavaleurspcifieparleconstructeurpardfautdutypeutilis.
266
Chapitre14.Lestypescomplmentaires
Exemple1421.Dcalagesetrotationsdevaleurs
#include <iostream>
#include <valarray>
usingnamespacestd;
voidaffiche(constvalarray
<double> &v)
{
size_ti;
for(i=0;i <v.size();++i)
cout << v[i] << "";
cout << endl;
}
intmain(void)
{
//Construitunvalarraydedoubles:
doublev1[]={1.1,2.2,3.3,4.4,5.5};
valarray<double> vect1(v1,5);
valarray<double> res(5);
//Effectueundcalagegauchededeuxpositions:
res=vect1.shift(2);
affiche(res);
//Effectueunerotationde2positionsversladroite:
res=vect1.cshift(2);
affiche(res);
return0;
}
14.3.2.2.Slectionmultipledeslmentsdunvalarray
Leslmentsdunvalarraypeuvent treaccdslaidedeloprateurdaccsauxlmentsde
tableau [].Lafonction affiche desexemplesduparagrapheprcdentutilisecettefonctionnalit
pourenrcuprerlavaleur.Cependant,lesvalarraydisposedemcanismesplussophistiquspour
manipulerleslmentsdestableauxdevaleurengroupe,afindebnficierdetouslesmcanismes
doptimisationquipeuventexistersuruneplateformedonne.Grcecesmcanismes,ilestpossible
deffectuerdesoprationssurdespartiesseulementdunvalarrayoudcriredenouvellesvaleurs
danscertainsdeseslmentsseulement.
Poureffectuercesslectionsmultiples,plusieurstechniquessontdisponibles.Cependant,toutesces
techniquessebasentsurlemmeprincipe,puisquellespermettentdefiltrerleslmentsduvalarray
pournenslectionnerquunepartieseulement.Lersultatdecefiltragepeuttreunnouveauvalarray
ouuneautreclassepouvanttremanipuleexactementdelammemanirequunvalarray.
Enpratique,ilexistequatremaniresdeslectionnerdeslmentsdansuntableau.Nousallonsles
dtaillerdanslessectionssuivantes.
267
Chapitre14.Lestypescomplmentaires
14.3.2.2.1. Slection par un masque
Lamanirelaplussimpleestdutiliserunmasquedeboolensindiquantquelslmentsdoiventtre
slectionnsounon.Lemasquedeboolensdoitobligatoirementtreunvalarraydemmedimension
quelevalarraycontenantleslmentsslectionner.Chaquelmentestdoncslectionnenfonction
delavaleurduboolencorrespondantdanslemasque.
Unefoislemasqueconstruit,laslectiondeslmentspeuttreralisesimplementenfournissant
cemasqueloprateur [] duvalarraycontenantleslmentsslectionner.
Lavaleurretourne
template mask_array, parlintermdiairede
parcetoprateurestalorsuneinstancedelaclasse
laquelleleslmentsslectionnspeuventtremanipuls.Pourlesvalarrayconstantscependant,la
valeurretourneestunautrevalarray,contenantunecopiedeslmentsslectionns.
Laclassemask_arrayfournitunnombrelimitdoprations. Enfait, sesinstancesnedoiventtre
utilisesquepoureffectuerdesoprationssimplessurleslmentsdutableauslectionnparle
masquefourniloprateur [].LesoprationsralisablesserontdcritesdanslaSection14.3.2.2.4.
Laslectiondeslmentsduntableauparlintermdiairedunmasqueestutilisecourammentavec
lesoprateursdecomparaisondesvalarray,puisqueceuxcirenvoientjustementuntelmasque.Ilest
donctrsfaciledeffectuerdesoprationssurleslmentsdunvalarrayquivrifientunecertaine
condition.
Exemple1422.Slectiondeslmentsdunvalarrayparunmasque
#include <iostream>
#include <valarray>
usingnamespacestd;
voidaffiche(constvalarray
<int> &v)
{
size_ti;
for(i=0;i <v.size();++i)
cout << v[i] << "";
cout << endl;
}
intmain(void)
{
//Construitunvalarraydentier:
intvaleurs[]={1,5,9,4,3,7,21,32};
valarray<int> vi(valeurs,
sizeof(valeurs)/sizeof(int));
affiche(vi);
//Multipliepar2touslesmultiplesde3:
vi[(vi%3)==0]*=valarray
<int>(2,vi.size());
affiche(vi);
return0;
}
268
Chapitre14.Lestypescomplmentaires
lmentsdutableau,mmepourceuxquinenousintressentpas.Ensuite,leslmentsslectionns
apparaissentsystmatiquementdanslemmeordrequeceluiquilsontdanslevalarraysource.
LabibliothquestandardC++fournitdoncunautremcanismedeslection,toujoursexplicite,mais
quipermetdefaireunerindexationdeslmentsainsislectionns.Cettefois,ilnefautplusfournir
unmasqueloprateur [],maisunvalarraycontenantdirectementlesindicesdeslmentsslec
tionns. Cesindicespeuvent nepastredanslordrecroissant, cequi permet doncderarranger
lordredeslmentsainsislectionns.
Exemple1423.Slectiondeslmentsdunvalarrayparindexation
#include <iostream>
#include <valarray>
usingnamespacestd;
voidaffiche(constvalarray
<int> &v)
{
size_ti;
for(i=0;i <v.size();++i)
cout << v[i] << "";
cout << endl;
}
intmain(void)
{
//Construitunvalarraydentier:
intvaleurs[]={1,5,9,4,3,7,21,32};
valarray<int> vi(valeurs,
sizeof(valeurs)/sizeof(int));
affiche(vi);
//Multipliepar2leslmentsdindices2,5et7:
size_tindices[]={2,5,7};
valarray<size_t> ind(indices,
sizeof(indices)/sizeof(size_t));
vi[ind]*=valarray<int>(2,ind.size());
affiche(vi);
return0;
}
Lavaleurretourneparloprateurdeslectionsurlesvalarraynonconstantsestcettefoisdutype
indirect_array. Commepourlaclassemask_array, lesoprationsralisablesparlintermdiairede
cetteclassesontlimitesetdoiventserviruniquementmodifierleslmentsslectionnsdansle
valarraysource.
269
Chapitre14.Lestypescomplmentaires
devaleursgnrerpourchaquevariableetlepasquisparecesvaleurs.Lesvariablesdecontrle
commencenttoutesleuritrationpartirdelavaleurnulleetprennentcommevaleurssuccessivesles
multiplesdupasquellesutilisent.
Note:Enralit,laclassesliceestuncasparticulierdelaclassegslicequinutilisequuneseule
variabledecontrlepourdfinirlesindices.Lesslicenesontdoncriendautrequedesgslice
unidimensionnels.
LetermedegsliceprovientdelanglaisGeneralizedSlice,quisignifiebienquelesgslicesont
desslicetenduesplusieursdimensions.
Exemple1424.Slectionparindexationimplicite
#include <iostream>
#include <valarray>
usingnamespacestd;
voidaffiche(constvalarray
<int> &v)
{
size_ti;
for(i=0;i <v.size();++i)
cout << v[i] << "";
cout << endl;
}
intmain(void)
{
//Construitunvalarraydentier:
intvaleurs[]={1,5,9,4,3,7,21,32};
valarray<int> vi(valeurs,8);
affiche(vi);
//Multipliepar2unlmentsur3partirdudeuxime:
slicesel(1,3,3);
vi[sel]*=valarray<int>(2,vi.size());
affiche(vi);
//Multipliepar2unlmentsur3partirdudeuxime:
slicesel(1,3,3);
270
Chapitre14.Lestypescomplmentaires
vi[sel]*=valarray<int>(2,vi.size());
affiche(vi);
return0;
}
Laclassegsliceestenrevancheunpeuplusdifficiledemploipuisquilfautdonnerlenombrede
valeursetlepaspourchaquevariabledecontrle.Leconstructeurutilisprenddoncendeuximeet
troisimeparamtresnonplusdeuxvaleursdetypesize_t,maisdeuxvalarraydesize_t.Ladclaration
delaclassegsliceestdonclasuivante:
classgslice
{
public:
gslice();
gslice(size_tdebut,
constvalarray<size_t> nombres,
constvalarray<size_t> pas);
//Accesseurs:
size_tstart()const;
valarray<size_t> size()const;
valarray<size_t> stride()const;
};
Lesdeuxvalarraydterminantlenombredevaleursdesvariablesdecontrleetleurspasdoiventbien
entenduavoirlammetaille.Lordredanslequellesindicesdeslmentsslectionnssontgnrs
parlaclassegsliceestceluiobtenuenfaisantvarierenpremierlesderniresvariablescaractrises
parlesvalarrayfournislorsdesaconstruction.Parexemple,uneclassegsliceutilisanttroisvariables
prenantrespectivement2,3et5valeursetvariantrespectivementparpasde3,1et2units,enpartant
delindice2,gnreralesindicessuivants:
2,4,6,8,10,
3,5,7,9,11,
4,6,8,10,12,
5,7,9,11,13,
6,8,10,12,14,
7,9,11,13,15
Lavariableprenantcinqvaleursetvariantdedeuxendeuxestdonccellequivolueleplusvite.
Commevouspouvezleconstateraveclexempleprcdent,unmmeindicepeutapparatreplusieurs
foisdanslasriedfinieparuneclassegslice.LabibliothquestandardC++neffectueaucuncontrle
ceniveau:ilestdoncduressortduprogrammeurdebienfaireattentioncequilfaitlorsquil
manipuledesjeuxdindicesdgnrs.
Commepourlesautrestechniquesdeslection,laslectiondlmentsdunvalarraynonconstantpar
lintermdiairedesclassessliceetgsliceretourneuneinstanceduneclasseparticulirepermettantde
prendreenchargelesoprationsdemodificationdeslmentsainsislectionns.Pourlesslections
simplesralisesaveclaclasseslice, lobjet retournest detypeslice_array. Pourlesslections
ralisesaveclaclassegslice,letypeutilisestletypegslice_array.
271
Chapitre14.Lestypescomplmentaires
14.3.2.2.4. Oprations ralisables sur les slections multiples
Commeonlavudanslessectionsprcdentes,lesslectionsmultiplesralisessurdesobjetsnon
constantsretournent desinstancesdesclassesutilitairesmask_array, indexed_array, slice_arrayet
gslice_array.Cesclassesrfrencentleslmentsainsislectionnsdanslevalarraysource,permet
tantainsidelesmanipulerengroupe.Cependant,cenesontpasdesvalarraycompletset,enfait,ils
nedoiventtreutiliss, demaniregnrale, quepoureffectueruneoprationdaffectationsurles
lmentsslectionns.Cesclassesutilisentdoncuneinterfacerestreintedecelledelaclassevalarray,
quinacceptequelesoprateursdaffectationsurleslmentsquellesreprsentent.
Parexemple,laclassemask_arrayestdclarecommesuitdanslentte valarray :
template <classT >
classmask_array
{
public:
typedefTvalue_type;
~mask_array();
//Oprateursdaffectationetdaffectationcomposes:
voidoperator=(constvalarray<T> &)const;
voidoperator*=(constvalarray<T> &)const;
voidoperator/=(constvalarray<T> &)const;
voidoperator%=(constvalarray<T> &)const;
voidoperator+=(constvalarray<T> &)const;
voidoperator=(constvalarray<T> &)const;
voidoperator^=(constvalarray<T> &)const;
voidoperator&=(constvalarray<T> &)const;
voidoperator|=(constvalarray<T> &)const;
voidoperator<<=(constvalarray<T> &)const;
voidoperator>>=(constvalarray<T> &)const;
voidoperator=(constT&valeur);
};
Touscesoprateurspermettentdaffecterauxlmentsdelaslectionreprsentsparcetteclasse
lesvaleursspcifiesparleurparamtre.Engnral,cesvaleursdoiventtrefourniessouslaforme
dunvalarray,maisilexistegalementunesurchargedeloprateurdaffectationpermettantdeleur
affectertousunemmevaleur.
Note:Lesslectionsralisessurlesvalarrayconstantsnepermettent bienentendupasde
modifierleurslments. Lesobjetsretournsparloprateur [] lorsdesslectionsmultiples
surcesobjetssontdoncdesvalarrayclassiquescontenantunecopiedesvaleursdeslments
slectionns.
14.3.3.Leschampsdebits
Detouslestypesdedonnesquunprogrammepeutavoirbesoindestocker,lesboolenssontcertai
nementlundesplusimportants.Eneffet,lesprogrammesdoiventsouventreprsenterdesproprits
qui sont soit vraies, soit fausses. Aprstout, labasedutraitement delinformationtellequil est
ralisparlesordinateursestlebit,ouchiffrebinaire...
272
Chapitre14.Lestypescomplmentaires
Ilexisteplusieursmaniresdestockerdesboolensdansunprogramme.Latechniquelaplussimple
estbienentendudutiliserletypeC++natifbool,quinepeutprendrequelesvaleurstrue et false.
Lesprogrammesplusvieuxutilisaientgnralementdesentiersetdesconstantesprdfiniesouen
coreunenumration. Malheureusement, toutescestechniquessouffrentdugrosinconvnientque
chaqueinformationeststockedansletypesousjacentautypeutilispourreprsenterlesboolens
et,danslaplupartdescas,cetypeestunentier.Celasignifiequepourstockerunbit,ilfautrserverun
motmmoirecomplet.MmeentenantcomptedufaitquelaplupartdescompilateursC++stockent
lesvariablesdetypebooldansdesimplesoctets,ladperditionrestedansunfacteur8.Bienentendu,
celanestpasgravesilonnaquequelquesbitsstocker,maissileprogrammedoitmanipulerun
grandnombredinformationsboolennes,cettetechniqueestproscrire.
NousavonsvudanslaSection3.1.4quilestpossiblededfinirdeschampsdebitsenattribuant
unnombredebitsfixeplusieursidentificateursdetypeentier.
Cettesolutionpeut permettre
dconomiserdelammoire,maisrestemalgrtoutrelativementlimitesiungrandnombredebits
doit tremanipul. Afindersoudreceproblme, labibliothquestandardC++fournit laclasse
template bitsetqui,commesonnomlindique,encapsuledeschampsdebitsdetaillesarbitraires.
Leparamtre template est detypesize_t et indiquelenombredebitsquelechampdebits
encapsulcontient.
Note:Vousnoterezquecelaimposedeconnatrelacompilationlatailleduchampdebits.
Celaestregrettableetlimitesrieusementlintrtdecetteclasse.Sivousdevezmanipulerdes
champsdebitsdetailledynamique,vousdevrezcrirevousmmeuneclassedencapsulation
dynamiquedeschampsdebits.
Laclassebitsetestdclarecommesuitdanslentte bitset :
template <size_tN >
classbitset
{
public:
classreference;
//Classepermettantdemanipulerlesbits.
//Lesconstructeurs:
bitset();
bitset(unsignedlongval);
template<classcharT,classtraits,classAllocator
>
explicitbitset(
constbasic_string<charT,traits,Allocator> &chaine,
typenamebasic_string<charT,traits,Allocator
>::size_typedebut=0,
typenamebasic_string<charT,traits,Allocator
>::size_typetaille=
basic_string<charT,traits,Allocator
>::npos);
//Lesfonctionsdeconversion:
unsignedlongto_ulong()const;
template <classcharT,classtraits,classAllocator
>
basic_string<charT,traits,Allocator> to_string()const;
//Lesoprateursdemanipulation:
bitset<N> &operator&=(constbitset<N> &);
bitset<N> &operator|=(constbitset<N> &);
bitset<N> &operator^=(constbitset<N> &);
bitset<N> &operator<<=(size_tpos);
bitset<N> &operator>>=(size_tpos);
bitset<N> operator<<(size_tpos)const;
273
Chapitre14.Lestypescomplmentaires
bitset<N> operator>>(size_tpos)const;
bitset<N> operator~()const;
bitset<N> &set();
bitset<N> &set(size_tpos,boolval=true);
bitset<N> &reset();
bitset<N> &reset(size_tpos);
bitset<N> &flip();
bitset<N> &flip(size_tpos);
booltest(size_tpos)const;
referenceoperator[](size_tpos); //forb[i];
//Lesoprateursdecomparaison:
booloperator==(constbitset<N> &rhs)const;
booloperator!=(constbitset<N> &rhs)const;
//Lesfonctionsdetest:
size_tcount()const;
size_tsize()const;
boolany()const;
boolnone()const;
};
Laconstructiondunchampdebitsncessitedeconnatrelenombredebitsquecechampdoitconte
nirafindinstancierlaclasse template bitset.Lesdiffrentsconstructeurspermettentdinitialiserle
champdebitsenaffectantlavaleurnulletoussesbitsouenlesinitialisantenfonctiondespara
mtresduconstructeur. Ledeuximeconstructeuraffecteraauxpremiersbitsduchampdebitsles
bitscorrespondantdelentierdetypeunsignedlongfournienparamtre,etinitialiseralesautresbits
duchampdebitslavaleur0siceluicicontientplusdebitsquununsignedlong.
Letroisime
constructeurinitialiselechampdebitspartirdesareprsentationsousformedechanedecarac
tresnecontenantquedes 0oudes 1.Cettereprsentationdoittrestockedanslabasic_string
fournieenpremierparamtre,partirdelapositiondebut etsurunelongueurde taille caractres.
Cettetaillepeuttreinfrieurelatailleduchampdebits.Danscecas,leconstructeurconsidrera
quelesbitsdepoidsfortsonttousnulsetinitialiseralespremiersbitsduchampaveclesvaleurslues
danslachane.Notezbienquelespremierscaractresdelachanedecaractresreprsententlesbits
depoidsfort,cettechaneestdoncparcourueensensinverselorsdelinitialisation.Ceconstructeur
estsusceptibledelanceruneexception out_of_range sileparamtre debut estsuprieurlataille
delachaneouuneexception invalid_argument silundescaractresutilissestdiffrentdes
caractres 0ou 1.
Commevouspouvezleconstaterdaprsladclaration,
laclassebitsetfournitgalementdesm
thodespermettantdeffectuerlesconversionsinversesdecelleseffectuesparlesconstructeurs.La
mthode to_ulong renvoiedoncunentierdetypeunsignedlongcorrespondantlavaleurdespre
templateto_stringrenvoieunechanedecaractres
miersbitsduchampdebits,etlamthode
contenantlareprsentationduchampdebitssouslaformedunesuitedecaractres 0et 1. La
classebitsetfournitgalementdessurchargesdesoprateurs operator<< et operator>> pourles
fluxdentre/sortiedelabibliothquestandard.
Exemple1425.Utilisationdunbitset
#include <iostream>
#include <bitset>
#include <string>
usingnamespacestd;
274
Chapitre14.Lestypescomplmentaires
intmain(void)
{
//Construitunchampdebits:
strings("100110101");
bitset<32> bs(s);
//Affichelavaleurenhexadcimaldelentierassoci:
cout << hex << showbase << bs.to_ulong() << endl;
//Affichelavaleursousformedechanedecaractres:
stringt;
t=bs.to_string<string::value_type,string::traits_type,
string::allocator_type
>();
cout << t << endl;
//Utilisedirectement << surlefluxdesortie:
cout << bs << endl;
return0;
}
Note:Lamthode to_string estunefonction template neprenantpasdeparamtres.Lecom
pilateurnepeutdoncpasraliseruneinstanciationimplicitelorsdesonappel.Parconsquent,
vousdevrezfournirlalistedesparamtres template explicitementsi vousdsirezutilisercette
mthode.Ilestgnralementplussimpledcrirelavaleurdubitsetdansunfluxstandard.
Lesmodificateursdeformat deflux hex et showbase ont pour but deffectuer laffichagedes
entierssousformehexadcimale.Lapersonnalisationdesfluxdentre/sortieseradcriteen
dtaildansleChapitre15.
Lesoprateursdemanipulationdeschampsdebitsneposentpasdeproblmeparticulierpuisquils
ontlammesmantiquequelesoprateursstandardsdulangage,
ceciprsquilstravaillentsur
lensembledesbitsduchampenmmetemps.Leseuloprateurquidemandequelquesexplications
estloprateurdaccsunitaireauxbitsduchamp, savoirloprateur operator[]. Eneffet, cet
oprateurnepeutpasretournerunerfrencesurlebitdsignparsonargumentpuisquilnyapas
detypepourreprsenterlesbitsenC++.Parconsquent,lavaleurretourneestenralituneinstance
delasousclassereferencedelaclassebitset.Cettesousclasseencapsulelaccsindividuelauxbits
dunchampdebitset permet delesutiliserexactement commeunboolen. Enparticulier, il est
possibledefairedestestsdirectementsurcettevaleurainsiquedeluiaffectuerunevaleurboolenne.
Enfin,lasousclassereferencedisposedunemthode flip dontlerleestdinverserlavaleurdubit
auquellobjetreferencedonneaccs.
Laclasse template bitsetdisposegalementdemthodesspcifiquespermettantdemanipulerles
bitssansavoirrecoursloprateur operator[].Ilsagitdesmthodes test, set, reset et flip.
Lapremiremthodepermetdercuprerlavaleurcourantedundesbitsduchampdebits.
Elle
true silebitest 1 et false
prendenparamtrelenumrodecebitetrenvoieunboolenvalant
sinon.Lamthode set permetderinitialiserlechampdebitscompletenpositionnanttoussesbits
1oudefixermanuellementlavaleurdunbitparticulier.Latroisimemthodepermetderinitialiser
lechampdebitsenannulanttoussesbitsoudannulerunbitspcifique.
Enfin, lamthode flip
permet dinverserlavaleurdetouslesbitsduchampoudinverserlavaleurdunbit
spcifique.
Lessurchargesdesmthodesquitravaillentsurunseulbitprennenttoutesenpremierparamtrela
positiondubitdanslechampdebits.
Exemple1426.Manipulationdesbitsdunchampdebits
#include <iostream>
#include <string>
275
Chapitre14.Lestypescomplmentaires
#include <bitset>
usingnamespacestd;
intmain(void)
{
//Construitunchampdebits:
strings("10011010");
bitset<8> bs(s);
cout << bs << endl;
//Inverselechampdebits:
bs.flip();
cout << bs << endl;
//Fixelebitdepoidsfort:
bs.set(7,true);
cout << bs << endl;
//Annulele7mebitlaidedunerfrencedebit:
bs[6]=false;
cout << bs << endl;
//Anulelebitdepoidsfaibe:
bs.reset(0);
cout << bs << endl;
return0;
}
Enfin,laclassebitsetfournitquelquesmthodespermettantdeffectuerdestestssurleschampsde
count, size, any et
bits.Outrelesoprateursdecomparaisonclassiques,ellefournitlesmthodes
none.Lamthode count renvoielenombredebitspositionns1danslechampdebits.Lamthode
size renvoiequantellelatailleduchampdebits,cestdirelavaleurduparamtre
template
utilisepourinstancierlaclassebitset.Enfin,lesmthodes any et none renvoient true siunbitau
moinsduchampdebitsestpositionnousilssonttousnuls.
276
Chapitre15.Lesfluxdentre/sortie
NousavonsvudanslaSection8.12unexempledapplicationdesclassesdefluxdentre/sortiede
labibliothquepourlesentres/sortiesstandardsdesprogrammes.Enralit,cesclassesdegestion
desfluxsintgrentdansunehirarchiecomplexedeclassespermettantdemanipulerlesfluxdentre
/sortieetpasseulementpourlesentres/sortiesstandards.
Eneffet, afindefaciliterlamanipulationdesfluxdentre/
sortie, labibliothquestandardC++
template
fournittoutunensembledeclasses
.Cesclassessontparamtresparletypedebasedes
caractresquellesmanipulent. Bienentendu, lestypesdecaractreslesplusutilisssontlestype
charetwchar_t,maisilestpossibledutiliserapriorinimportequelautretypededonnepourlequel
uneclassedetraitschar_traitsestdfinie.
Cechapitreapourbutdedtaillercettehirarchiedeclasses.Lesprincipesdebaseetlarchitecture
gnraledesfluxC++serontdoncabordsdansunpremiertemps, puislesclassesdegestiondes
tamponsseronttraites. Lesclassesgnriquesdegestiondesfluxdentre/sortieserontensuite
dcrites,etceseraenfinletourdesclassesdegestiondesfluxorientschanesdecaractresetdes
classesdegestiondesfluxorientsfichiers.
15.1.Notionsdebaseetprsentationgnrale
Lesclassesdelabibliothquedentre/sortiedelabibliothquestandardsesubdivisentendeux
catgoriesdistinctes.
Lapremirecatgorieregroupelesclassesdegestiondestamponsdentre/sortie.Cesclassessont
aunombredetrois:laclasse template basic_stringbuf,quipermetderaliserdestamponspourles
fluxorientschanesdecaractres,laclasse template basic_filebuf,quiprendenchargelestampons
pourlesfluxorientsfichiers,etleurclassedebasecommune,laclasse template basic_streambuf.
Lerledecesclassesestprincipalementdoptimiserlesentres/sortiesenintercalantdestampons
dentre/sortieauseinmmeduprogramme.Cesontprincipalementdesclassesutilitaires,quisont
utiliseseninterneparlesautresclassesdelabibliothquedentre/sortie.
Ladeuximecatgoriedeclassesestdeloinlapluscomplexe,puisquilsagitdesclassesdegestion
desfluxeuxmmes.Toutescesclassesdriventdelaclassetemplate basic_ios(ellemmedrive
delaclassedebaseios_base, quidfinittouslestypesetlesconstantesutilissparlesclassesde
flux).Laclassebasic_iosfournitlesfonctionnalitsdebasedesclassesdefluxet,enparticulier,elle
grelelienaveclestamponsdentre/sortieutilissparleflux.Decetteclassedebasedriventdes
classesspcialisesrespectivementpourlesentresoupourlessorties.
Ainsi, laclasse template
basic_istreamprendenchargetouteslesoprationsdesfluxdentreet
laclassebasic_ostream
touteslesoprationsdesfluxdesortie. Enfin, labibliothquestandarddfinitlaclasse template
basic_iostream,quiregroupetouteslesfonctionnalitsdesclassesbasic_istreametbasic_ostreamet
dontdriventtouteslesclassesdegestiondesfluxmixtes.
Lesclassesbasic_istream, basic_ostreamet basic_iostreamfournissent lesfonctionnalitsdebase
desfluxdentre/sortie.Cesontdonclesclassesutilisespourimplmenterlesfluxdentre/sortie
standardsduC++ cin, cout, cerr et clog,quelonabrivementprsentsdanslaSection8.12.
Cependant,cesclassesneprennentpasenchargetouteslesspcificitsdesmdiasaveclesquelsdes
fluxpluscomplexespeuventcommuniquer. Parconsquent, desclassesdrives, plusspcialises,
sontfourniesparlabibliothquestandard. Cesclassesprennentenchargelesentres/sortiessur
fichieretlesfluxorientschanesdecaractres.
Labibliothquestandardfournit doncdeuxjeuxdeclassesspcialisespourlesentres/
sorties
dansdesfichiersetdansdeschanesdecaractres.Pourchacunedesclassesdebasebasic_istream,
277
Chapitre15.Lesfluxdentre/sortie
basic_ostreamet basic_iostreamil existedeuxclassesdrives, unepourlesfichiers, et unepour
leschanesdecaractres.Parexemple,lesclasses template basic_ifstreametbasic_istringstream
driventdelaclassebasic_istreametprennentenchargerespectivementlesfluxdentrepartirde
fichiersetlesfluxdentrepartirdechanesdecaractres.Demme,labibliothquestandarddfinit
lesclasses template basic_ofstreamet basic_ostringstream, drivesdelaclassebasic_ostream,
template
pourlesfluxdesortiedansdesfichiersoudansdeschanesdecaractres,etlesclasses
basic_fstreamet basic_stringstream, drivesdelaclassebasic_iostream, pourlesfluxdentre/
sortiesurlesfichiersetleschanesdecaractres.
Note: Cettehirarchiedeclassesest assezcomplexeet peut paratretrangeauniveau
desclassesdesfluxmixtes. Eneffet, laclassebasic_fstreamnedrivepasdesclasses
basic_ifstreamet basic_ofstreammaisdelaclassebasic_iostream, et cest cetteclassequi
drivedesclassesbasic_istreamet basic_ostream. Demme, laclassebasic_stringstream
nedrivepasdesclassesbasic_istringstreamet
basic_ostringstream, maisdelaclasse
basic_iostream.
streambuf;
wstreambuf;
stringbuf;
wstringbuf;
filebuf;
wfilebuf;
//Typesdebasedesfluxdentre/sortie:
typedefbasic_ios<char>
ios;
typedefbasic_ios<wchar_t> wios;
//Typesdesfluxdentre/sortiestandards:
typedefbasic_istream<char>
istream;
typedefbasic_istream<wchar_t> wistream;
typedefbasic_ostream<char>
ostream;
typedefbasic_ostream<wchar_t> wostream;
typedefbasic_iostream<char>
iostream;
typedefbasic_iostream<wchar_t> wiostream;
//Typesdesfluxorientsfichiers:
typedefbasic_ifstream<char>
ifstream;
typedefbasic_ifstream<wchar_t> wifstream;
typedefbasic_ofstream<char>
ofstream;
278
Chapitre15.Lesfluxdentre/sortie
typedefbasic_ofstream<wchar_t> wofstream;
typedefbasic_fstream<char>
fstream;
typedefbasic_fstream<wchar_t> wfstream;
//Typesdesfluxorientschanesdecaractres:
typedefbasic_istringstream
istringstream;
<char>
typedefbasic_istringstream
<wchar_t> wistringstream;
typedefbasic_ostringstream
ostringstream;
<char>
typedefbasic_ostringstream
<wchar_t> wostringstream;
typedefbasic_stringstream
stringstream;
<char>
typedefbasic_stringstream
<wchar_t> wstringstream;
15.2.Lestampons
LesclassesdegestiondestamponsdelabibliothquestandardC++sesituentaucoeurdesoprations
dcritureetdelecturesurlesfluxdedonnesphysiquesquunprogrammeestsusceptibledemani
puler.Bienquellesnesoientquasimentjamaisutilisesdirectementparlesprogrammeurs,cestsur
cesclassesquelesclassesdefluxsappuientpoureffectuerlesoprationsdentresortie.Ilestdonc
ncessairedeconnatreunpeuleurmodedefonctionnement.
15.2.1.Gnralitssurlestampons
Untampon,galementappelcache,estunezonemmoiredanslaquellelesoprationsdcritureet
delecturesefontetdontlecontenuestmisencorrespondanceaveclesdonnesdunmdiaphysique
sousjacent. Lesmcanismesdecacheont essentiellement pourbut doptimiserlesperformances
desoprationsdentre/ sortie. Eneffet, laccslammoirecacheest gnralement beaucoup
plusrapidequelaccsdirectausupportphysiqueouaumdiadecommunication. Lesoprations
effectuesparleprogrammesefontdonc,laplupartdutemps,uniquementauniveaudutampon,et
cenestquedanscertainesconditionsquelesdonnesdutamponsonteffectivementtransmisesau
mdiaphysique.Legainenperformancepeutintervenirplusieursniveau.Lescaslesplussimples
tantsimplementlorsquunedonnecriteestcrasepeudetempsaprsparuneautrevaleur(la
premireoprationdcriturenestalorsjamaistransmiseaumdia)oulorsquunedonneestlue
279
Chapitre15.Lesfluxdentre/sortie
plusieursfois(lammedonneestrenvoyechaquelecture).Bienentendu,celasupposequeles
donnesstockesdansletamponsoientcohrentesaveclesdonnesdumdia,surtoutsilesdonnes
sontaccdesautraversdeplusieurstampons.Toutmcanismedegestiondecachepermetdoncde
viderlescaches(cestdiredeforcerlesoprationsdcriture)etdelesinvalider(cestdirede
leursignalerqueleursdonnessontobsoltesetquunelecturephysiquedoittrefaitesioncherche
yaccder).
Lesmcanismesdemmoirecacheetdetamponsonttrssouventutilisseninformatique,tousles
niveaux.Ontrouvedesmmoirescachedanslesprocesseurs,lescontrleursdedisque,lesgraveurs
deCD,lespilotesdepriphriquesdessystmesdexploitationetbienentendudanslesprogrammes.
Chacundecescachescontribuelamliorationdesperformancesglobalesenretardantaumaximum
laralisationdesoprationslentesetenoptimisantlesoprationsdelectureetdcriture(souventen
leseffectuantengroupe,cequipermetderduirelesfraisdecommunicationoudinitialisationdes
priphriques).IlnestdoncabsolumentpassurprenantquelabibliothquestandardC++utiliseelle
aussilanotiondetampondanstoutessesclassesdentre/sortie...
15.2.2.Laclassebasic_streambuf
Lesmcanismesdebasedestamponsdelabibliothquestandardsontimplmentsdanslaclasse
template basic_streambuf.Cetteclassenestpasdestinetreutilisetellequellecarellenesait
pascommuniqueraveclessupportsphysiquesdesdonnes.Enfait,ellenepeuttreutilisequen
tantqueclassedebasedeclassesplusspcialises,quiellesfournissentlesfonctionnalitsdaccs
auxmdiasparlintermdiairedefonctionsvirtuelles.Laclassebasic_streambuf appelledoncces
mthodesendiversescirconstancesauseindestraitementseffectusparsonproprecodedegestion
dutampon,aussibienpoursignalerleschangementsdtatdeceluiciquepourdemanderlcriture
oulalecturedesdonnesdanslasquencesouscontrle.
Laclassebasic_streambuffournitdoncuneinterfacepubliquepermettantdaccderauxdonnesdu
tampondunctetdfinitlinterfacedecommunicationavecsesclassesfillesparlintermdiairede
sesmthodesvirtuellesdelautrecot.Bienentendu,cesmthodesvirtuellessonttoutesdclares
enzoneprotgeafindviterquelonpuisselesappelerdirectement,toutenpermettantauxclasses
drivesdelesredfiniretdyaccder.
Eninterne, laclassebasic_streambufencapsuledeuxtampons, unpourlescrituresetunpourles
lectures. Cependant, cestamponsaccdentlammemmoireetlammesquencededonnes
physiques. Cesdeuxtamponspeuvent treutilisssimultanment ounon, suivant lanaturedela
squencesouscontrleetsuivantlefluxquiutiliseletampon.Parexemple,lesfluxdesortienutilisent
queletamponencriture,etlesfluxdentrequeletamponenlecture.
Laclassebasic_streambufgresestamponsdentreet desortielaidedunezonedemmoire
internequicontientunsousensembledesdonnesdelasquencesouscontrle.Lesdeuxtampons
travaillentdemanireindpendantesurcettezonedemmoireetsontchacunreprsentslaide
detroispointeurs.Cespointeurscontiennentrespectivementladressedudbutdelazonemmoire
dutampon, sonadressedefinet ladressedelapositioncouranteenlectureouencriture.
Ces
pointeurssontcompltementgrseninterneparlaclassebasic_streambuf,maislesclassesdrives
peuventyaccderetlesmodifierenfonctiondeleursbesoinsparlintermdiairedaccesseurs.Les
pointeursduntamponpeuvent parfaitement trenulssi celuici nest pasutilis. Toutefois, si le
pointeurrfrenantlapositioncourantenestpasnul,sespointeursassocisnedoiventpasltreet
lapositioncouranterfrencedoitobligatoirementsesituerdansunezonemmoiredfinieparles
pointeursdedbutetdefindutampon.
Laclassebasic_streambufestdclarecommesuitdanslentte streambuf :
template <classcharT,classtraits=
280
Chapitre15.Lesfluxdentre/sortie
char_traits<charT>>
classbasic_streambuf
{
public:
//Lestypesdebase:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
typedeftraits
traits_type;
//Lesmthodespubliquesutilisablesparlesclassesdeflux:
//Lesmthodesdegestiondeslocales:
localepubimbue(constlocale&loc);
localegetloc()const;
//Lesmthodesdegestiondutampon:
basic_streambuf<char_type,traits> *
pubsetbuf(char_type*s,streamsizen);
pos_typepubseekoff(off_typeoff,ios_base::seekdirsens,
ios_base::openmodemode=ios_base::in|ios_base::out);
pos_typepubseekpos(pos_typesp,
ios_base::openmodemode=ios_base::in|ios_base::out);
intpubsync();
//Mthodesdaccsautamponenlecture:
streamsizein_avail();
int_typesgetc();
int_typesbumpc();
int_typesnextc();
streamsizesgetn(char_type*s,streamsizen);
//Mthodedannulationdelectureduncaractre:
int_typesputbackc(char_typec);
int_typesungetc();
//Mthodedaccsencriture:
int_type
sputc(char_typec);
streamsizesputn(constchar_type*s,streamsizen);
//Ledestructeur:
virtual~basic_streambuf();
protected:
//Lesmthodesprotectedutilisablespar
//lesclassesdrives:
//Leconstructeur:
basic_streambuf();
//Mthodesdaccsauxpointeursdutampondelecture:
char_type*eback()const;
char_type*gptr() const;
char_type*egptr()const;
void
gbump(intn);
void
setg(char_type*debut,char_type*suivant,
281
Chapitre15.Lesfluxdentre/sortie
char_type*fin);
//Mthodesdaccsauxpointeursdutampondcriture:
char_type*pbase()const;
char_type*pptr()const;
char_type*epptr()const;
void
pbump(intn);
void
setp(char_type*debut,char_type*fin);
//Lesmthodesprotectedvirtuelles,quelesclasses
//drivesdoiventimplmenter:
virtualvoidimbue(constlocale&loc);
virtualbasic_streambuf<char_type,traits>*
setbuf(char_type*s,streamsizen);
virtualpos_typeseekoff(off_typeoff,ios_base::seekdirsens,
ios_base::openmodemode=ios_base::in|ios_base::out);
virtualpos_typeseekpos(pos_typesp,
ios_base::openmodemode=ios_base::in|ios_base::out);
virtualint
sync();
virtualint
showmanyc();
virtualstreamsizexsgetn(char_type*s,streamsizen);
virtualint_type
underflow();
virtualint_type
uflow();
virtualint_type
pbackfail(int_typec=traits::eof());
virtualstreamsizexsputn(constchar_type*s,streamsizen);
virtualint_type
overflow(int_typec=traits::eof());
};
Commevouspouvezleconstater, leconstructeurdelaclassebasic_streambufestdclarenzone
protected,cequiempchequiconquedelinstancier.Cestnormal,puisquecetteclassenestdesti
netreutilisequentantqueclassedebaseduneclassespcialisepourunmdiaspcifique.En
revanche,lesmthodesvirtuellesnesontpaspures,carellesfournissentuncomportementpardfaut
quiconviendradanslaplupartdescas.
Linterfacepubliquecomprenddesmthodesdordregnraleetdesmthodespermettantdeffectuer
lesoprationsdcritureetdelecturesurlestamponsencapsulsparlaclassebasic_streambuf.Pour
lesdistinguerdesmthodesvirtuellesquidoiventtreimplmentesdanslesclassesdrives,leur
nomestprfixpar pub (pourpublique).
Lesmthodes pubimbue et locale permettentrespectivementdefixerlalocaleutiliseparlepro
grammepourcetamponetdercuprerlalocalecourante. Pardfaut, lalocaleglobaleactiveau
momentdelaconstructiondutamponestutilise.LesnotionsdelocalesserontdcritesdansleCha
pitre16.
Lesmthodes pubsetbuf, pubseekoff et pubseekpos permettent quant ellesdeparamtrer
letampondentre/sortie. Cesmthodessecontententdappelerlesmthodesvirtuelles setbuf,
seekoff et seekpos, dont lecomportement, spcifiquechaqueclassedrive, seradcrit ci
dessous.
Viennentensuitelesmthodesdaccsauxdonnesenlectureetencriture.Lesmthodesdelecture
sontrespectivementlesmthodes sgetc, sbumpc et snextc.Lamthode sgetc permetdelirela
valeurducaractrerfrencparlepointeurcourantdutampondentre.
Cettefonctionrenvoiela
mmevaleurchaqueappel,carellenemodifiepaslavaleurdecepointeur.Enrevanche,lamthode
sbumpc faitavancercepointeuraprslalectureducaractrecourant,
cequifaitquellepeuttre
utilisepourliretouslescaractresdufluxdedonnesphysiques.Enfin,lamthode snextc appelle
282
Chapitre15.Lesfluxdentre/sortie
lamthode sbumpc dansunpremiertemps,puisrenvoielavaleurretourneparsgetc.Cettemthode
permetdoncdelirelavaleurducaractresuivantdansletamponetdepositionnerlepointeursurce
caractre.Notezque,contrairementlamthode sbumpc, snextc modifielavaleurdupointeuravant
delirelecaractrecourant,cequifaitquenralitellelitlecaractresuivant.Toutescesmthodes
renvoientlavaleurdefindefichierdfiniedanslaclassedestraitsdutypedecaractreutilisencas
derreur.Ellessontgalementsusceptiblesdedemanderlalecturededonnescomplmentairesdans
lecadredelagestiondutampon.
Lamthode in_avail renvoielenombredecaractresencorestocksdansletampongrparla
classebasic_streambuf.Sicetamponestvide,ellerenvoieuneestimationdunombredecaractres
quipeuventtrelusdanslasquencecontrleparletampon.Cetteestimationestunminimum,la
valeurrenvoyegarantitquautantdappel sbumpc russiront.
Lestamponsdelabibliothquestandarddonnent lapossibilitauxprogrammesqui lesutilisent
dannulerlalectureduncaractre.Normalement,cegenredannulationnepeuttreeffectuquune
seulefoisetlavaleurquidoittrereplacedansletampondoittreexactementcellequiavaitt
lue. Lesmthodesquipermettentdeffectuercetypedoprationsontlesmthodes sputbackc et
sungetc.Lapremiremthodeprendenparamtrelavaleurducaractrequidoittrereplacdans
letamponetladeuximenefaitquedcrmenterlepointeurrfrenantllmentcourantdansle
tampondelecture.Cesdeuxoprationspeuventchouersilavaleurreplacernestpasgalela
valeurducaractrequisetrouvedansletamponousi,toutsimplement,ilestimpossiblederevenir
enarrire(parexempleparcequonsetrouveendbutdesquence).Danscecas,cesmthodesren
voientlavaleurdefindefichierdfiniedanslaclassedestraitsdutypedecaractreutilis,savoir
traits::eof().
Enfin,lesmthodesdcrituredelaclassebasic_streambufsontlesmthodes sputc et sputn.La
premirepermetdcrireuncaractreuniquedansletampondelasquencedesortieetladeuxime
dcriretouteunesriedecaractres.Danscederniercas,lescaractrescriresontspcifislaide
duntableaudontlalongueurestpasseendeuximeparamtresputn.Cesdeuxmthodespeuvent
renvoyerlecaractredefindefichierdelaclassedestraitsdutypedecaractreutilispoursignaler
uneerreurdcriture.
Linterfaceprotgedelaclassebasic_streambufestconstituedesaccesseursauxpointeurssurles
tamponsdentreetdesortiedunepartet,dautrepart,desmthodesvirtuellesquelesclassesdri
vesdoiventredfinirpourimplmenterlagestiondesentres/sortiesphysiques.
Lespointeursdutableaucontenantlesdonnesdutampondelecturepeuventtrercuprsparles
classesdriveslaidedesmthodes eback, gptr et egptr.Lamthode eback renvoielepointeur
surledbutdutableaudutampondentre.Lesmthodes gptr et egptr renvoientquantellesle
pointeursurllmentcourant,dontlavaleurpeuttreobtenueaveclamthodesgetc,etlepointeur
surlafindutableaudutampon.Lenomdelamthode gptr provientdelabrviationdelanglais
getpointeretceluidelamthode egptr delabrviationendofgptr. Enfin, lesmthodes
gbump et setg permettent respectivement defaireavancerlepointeursurllment courant dun
certainnombredepositionsetdefixerlestroispointeursdutampondelectureenuneseuleopration.
Lespointeursdutampondcrituresont accessiblespardesmthodessimilairescellesdfinies
pourletampondelecture. Ainsi, lesmthodes pbase, pptr et epptr permettentrespectivement
daccderaudbut dutableaucontenant lesdonnesdutampondcriture, lapositioncourante
pourlescrituresetaupointeurdefindecetableau.pptresticilabrviationdelanglaisput
pointer.Lesmthodes pbump et setp jouentlemmerlepourlespointeursdutampondcriture
quelesmthodes gbump et setg pourlespointeursdutampondelecture.
Enfin, lesmthodesprotgesdelaclassebasic_streambufpermettent, commeonladjindiqu
cidessus,decommuniqueraveclesclassesdrivesimplmentantlesentres/sortiesphysiques.Le
rledecesmthodesestdcritdansletableaucidessous:
283
Chapitre15.Lesfluxdentre/sortie
Mthode
284
Description
imbue
Cettemthodeestappelechaquefoisquilyaunchangementdelocaleau
niveaudutampon.Lesclassesdrivesdelaclassebasic_streambufsont
assuresquilnyaurapasdechangementdelocaleentrechaqueappelcette
fonctionetpeuventdoncmaintenirunerfrencesurlalocalecouranteen
permanence.Lesnotionsconcernantleslocalesserontdcritesdansle
Chapitre16.
setbuf
Cettemthodenestappelequeparlamthode pubsetbuf.Ellea
principalementpourbutdefixerlazonemmoireutiliseparletampon.Ceci
peutnepasavoirdesenspourcertainsmdias,aussicettemthodepeutellene
rienfairedutout.Enpratique,sicettefonctionestappelleavecdeux
paramtresnuls,lesmcanismesdegestionducachedoiventtredsactivs.
Pourcela,laclassedrivedoitfixerlespointeursdestamponsdelectureet
dcriturelavaleurnulle.
seekoff
Cettemthodenestappelequeparlamthode pubseekoff.Toutcommela
mthode setbuf,sasmantiqueestspcifiquechaqueclassedrivede
gestiondesmdiasphysiques.Engnral,cettefonctionpermetdedplacerla
positioncourantedanslasquencededonnesduncertaindcalage.Ce
dcalagepeuttrespcifirelativementlapositioncourante,audbutoula
findelasquencededonnessouscontrle.Lemodededplacementest
spcifilaideduparamtre sens,quidoitprendrelunedesconstantesde
typeseekdirdfiniedanslaclasseios_base.Demme,letamponconcernpar
cedplacementestspcifiparleparamtre mode,dontlavaleurdoittre
lunedesconstantedetypeios_base::openmode.Cestypesetcesconstantes
serontdcritsaveclaclassedebaseios_basedanslaSection15.3.
seekpos
Cettemthodenestappelequeparlamthode pubseekpos.Ellefonctionne
demaniresimilairelamthode seekoff puisquellepermetdepositionner
lepointeurcourantdestamponsdelaclassebasic_streambufun
emplacementarbitrairedanslasquencededonnessouscontrle.
sync
showmanyc
xsgetn
Cettemthodenestappelequeparlamthode sgetn.Ellepermetdeffectuer
lalecturedeplusieurscaractresetdelesstockerdansletableaureuen
paramtre.Lalecturedechaquecaractredoitsefaireexactementcommesila
mthode sbumpc taitappelesuccessivementpourchacundeuxafinde
maintenirletampondelecturedansuntatcohrent.Lavaleurretourneestle
nombredecaractreseffectivementlusou traits::eof() encasderreur.
Chapitre15.Lesfluxdentre/sortie
Mthode
underflow
Description
Cettemthodeestappelelorsquelafindutamponestatteintelorsdela
lectureduncaractre.Celapeutseproduirelorsquilnyaplusdecaractre
disponibledansletamponoutoutsimplementchaquelecture,lorsquele
mcanismedecacheestdsactiv.Cettefonctiondoitrenvoyerlecaractre
suivantdelasquencesouscontrleetremplirletamponsincessaire.Le
pointeurrfrenantlecaractrecourantestalorsinitialissurlecaractredont
lavaleuratrcupre.Ainsi,lamthode underflow doitremplirle
tampon,maisnedoitpasfaireavancerlapositioncourantedelecture.Cette
mthodepeutrenvoyer traits::eof() encasdchec,cequiseproduit
gnralementlorsquelafindelasquencesouscontrleatatteinte.
uflow
Cettemthodeestappeledanslesmmesconditionsquelamthode
underflow.Elledoitgalementremplirletampon,mais,contrairement
underflow,ellefaitgalementavancerlepointeurducaractrecourantdune
position.Ceciimpliquequecettemthodenepeutpastreutiliseaveclesflux
nonbufferiss.Engnral,cettemthodenapastreredfinieparcequele
codedelamthode uflow delaclassebasic_streambufeffectuecesoprations
ensappuyantsurlamthode underflow.Cettemthodepeutrenvoyer
traits::eof() encasdchec.
pbackfail
xsputn
Cettemthodenestappelequeparlamthode sputn.Ellepermetderaliser
lcrituredeplusieurscaractresdanslasquencedesortie.Cescaractressont
spcifisdansletableaufournienparamtre.Cescrituressontralises
exactementcommesilamthode sputc taitappelesuccessivementpour
chaquecaractreafindemaintenirletampondcrituredansuntatcohrent.
Lavaleurretourneestlenombredecaractrescritsou traits::eof() en
casderreur.
overflow
Cettemthodeestappeleparlesmthodesdcrituredelaclasse
basic_streambuflorsqueletampondcritureestplein.Elleapourbutde
dgagerdelaplacedanscetamponenconsommantunepartiedescaractres
situsentrelepointeurdedbutdutamponetlepointeurdepositiondcriture
courante.Elleestdoncsusceptibledeffectuerlescrituresphysiquessurle
mdiadesortieaucoursdecetteopration.Silcriturerussit,lespointeurs
degestiondutampondcrituredoiventtremisjourenconsquence.Dans
lecascontraire,lafonctionpeutrenvoyerlavaleur traits::eof() pour
signalerlerreuroulanceruneexception.
15.2.3.Lesclassesdetamponsbasic_streambufet
285
Chapitre15.Lesfluxdentre/sortie
basic_filebuf
Vouslaurezcompris,lcritureduneclassedrivedelaclassebasic_streambufprenantencharge
unmdiapeuttrerelativementtechniqueetdifficile. Heureusement, cettesituationneseprsente
quasiment jamais, parcequelabibliothquestandardC++fournit desclassesdrivesprenant en
chargelesdeuxsituationslesplusimportantes:lestamponsdaccsunechanedecaractresetles
tamponsdaccsauxfichiers.Cesclassessontrespectivementlesclasses template basic_stringbuf
etbasic_filebuf.
15.2.3.1.Laclassebasic_stringbuf
Laclassebasic_stringbufpermetdeffectuerdesentres/sortiesenmmoiredelammemanire
quesi ellestaient effectuessurunpriphriquedentre/ sortienormal. Lebut decetteclasse
nestvidemmentpasdoptimiserlesperformanceslaideduncachepuisquelesoprationssefont
destinationdelammoire,maisduniformiseretdepermettrelesmmesoprationsdeformatage
dansdeschanesdecaractresquecellesquelonpeutraliseraveclesfluxdentre/sortienormaux.
Laclassebasic_streambufdrivebienentendudelaclassebasic_streambufpuisquelledfinitles
oprationsfondamentalesdcritureet delecturedansunechanedecaractres. Elleest dclare
commesuitdanslentte sstream :
template <classcharT,
classtraits=char_traits
<charT>,
classAllocator=allocator
<chatT>>
classbasic_stringbuf:publicbasic_streambuf <charT,traits>
{
public:
//Lestypes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
typedeftraits
traits_type;
//Lesconstructeurs/destructeurs:
explicitbasic_stringbuf(
ios_base::openmodemode=ios_base::in|ios_base::out);
explicitbasic_stringbuf(
constbasic_string<charT,traits,Allocator> &str,
ios_base::openmodemode=ios_base::in|ios_base::out);
virtual~basic_stringbuf();
//Lesmthodesdegestiondelachanedecaractressouscontrle:
basic_string<charT,traits,Allocator
> str()const;
voidstr(constbasic_string
<charT,traits,Allocator> &s);
};
Commecettedclarationlemontre,laclassebasic_streambufdfinitelleaussiunjeudetypespermet
tantdobtenirfacilementlestypesdeobjetsmanipuls.Deplus,elledfinitgalementquelquesm
thodescomplmentairespermettantdeffectuerlesoprationsspcifiquesauxfluxorientschanede
caractres.Enparticulier,lesconstructeurspermettentdefournirunechanedecaractrespartirde
laquelleletamponserainitialis.Cettechanedecaractresestcopielorsdelaconstructiondutam
pon,cequifaitquellepeuttrerutiliseoumodifieaprslacrationdutampon.Cesconstructeurs
prennentgalementenparamtrelemodedefonctionnementdutampon.Cemodepeuttrelalecture
286
Chapitre15.Lesfluxdentre/sortie
(auquelcasleparamtre mode vaut ios_base::in),lcriture( mode vautalors ios_base::out)
oulesdeux( mode vautalorslacombinaisondecesdeuxconstantesparunoulogique).Lesconstantes
demodedouverturesontdfinisdanslaclasseios_base,quelondcriradanslaSection15.3.
Note:Vousremarquerezque,contrairementauconstructeurdelaclassebasic_streambuf,les
constructeursdelaclassebasic_stringbuf sontdclarsdanslazonededclarationpublique,
cequi autoriselacrationdetamponsdetypebasic_stringbuf.Leconstructeurdelaclassede
baseestappelparcesconstructeurs,qui ontledroitdelefairepuisquil sagitdunemthode
protected.
Ilestgalementpossibledaccderauxdonnesstockesdansletamponlaidedesaccesseurs str.
Lepremierrenvoieunebasic_stringcontenantlachanedutamponencrituresipossible(cestdire
siletamponatcrdanslemodecritureoulecture/criture),etlachanedutamponenlecture
sinon.Ledeuximeaccesseurpermetdedfinirlesdonnesdutamponaposteriori,unefoisceluici
cr.
Exemple151.Lectureetcrituredansuntampondechanedecaractres
#include <iostream>
#include <string>
#include <sstream>
usingnamespacestd;
intmain(void)
{
//Construitunechanedecaractre:
strings("123456789");
//Construituntamponbassurcettechane:
stringbufsb(s);
//Litquelquescaractresunitairement:
cout << (char)sb.sbumpc() << endl;
cout << (char)sb.sbumpc() << endl;
cout << (char)sb.sbumpc() << endl;
//Replacelederniercaractreludansletampon:
sb.sungetc();
//Littroiscaractresconscutivement:
chartab[4];
sb.sgetn(tab,3);
tab[3]=0;
cout << tab << endl;
//craselepremiercaractredelachane:
sb.sputc(a);
//Rcupreunecopiedelachaneutiliseparletampon:
cout << sb.str() << endl;
return0;
}
Note:Laclassebasic_stringbufredfinitbienentenducertainesdesmthodesprotgesdela
classebasic_streambuf.Cesmthodesnontpastprsentesdansladclarationcidessus
parcequellesfontpartiedelimplmentationdelaclassebasic_stringbufetleurdescriptionna
quepeudintrtpourlesutilisateurs.
287
Chapitre15.Lesfluxdentre/sortie
15.2.3.2.Laclassebasic_filebuf
Laclassebasic_filebufestlaclassequiprendenchargelesoprationsdentre/sortiesurfichierdans
labibliothquestandardC++.
PourlabibliothquestandardC++,unfichierestunesquencedecaractressimples(doncdetype
char). Ilestimportantdebiencomprendrequilnestpaspossible,
aveclaclassebasic_filebuf, de
manipulerdesfichierscontenant desdonnesdetypewchar_t. Eneffet, mmedanslecasoles
donnesenregistressontdetypewchar_t,lesfichierscontenantcesdonnessontenregistrssousla
formedesquencesdecaractresdontlunitdebaserestelecaractresimple.Lamaniredecoder
lescaractreslargesdanslesfichiersnestpasspcifieetchaqueimplmentationestlibredefaire
cequelleveutceniveau.Gnralement,lencodageutilisestunencodagetaillevariable,cest
direquechaquecaractrelargeestreprsentsouslaformedunoudeplusieurscaractressimples,
selonsavaleuretselonsapositiondanslefluxdedonnesdufichier.
Celasignifiequil nefaut pasfairedhypothsesur lamaniredont lesinstancesdelaclasse
template basic_filebuf enregistrent les donnes des fichiers pour des valeurs duparamtre
templatecharT autres queletypechar. Engnral, lencodageutilisneconcernepas
le
programmeur, puisquil suffit denregistreret delirelesfichiersaveclesmmetypesdeclasses
basic_filebufpourretrouverlesdonnesinitiales. Toutefois, si lesfichiersdoivent trereluspar
desprogrammescritsdansunautrelangageoucompilsavecunautrecompilateur,
il peut tre
ncessairedeconnatrelencodageutilis. Voustrouverezcetteinformationdansladocumentation
devotreenvironnementdedveloppement.
Laclassebasic_filebufestdclarecommesuitdanslentte fstream :
template <classcharT,
classtraits=char_traits
<charT>>
classbasic_filebuf:publicbasic_streambuf<charT,traits>
{
public:
//Lestypes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
typedeftraits
traits_type;
//Lesconstructeurs/destructeurs:
basic_filebuf();
virtual~basic_filebuf();
//Lesmthodesdegestiondufichiersouscontrle:
basic_filebuf<charT,traits> *open(constchar*s,
ios_base::openmodemode);
basic_filebuf<charT,traits> *close();
boolis_open()const;
};
Commevouspouvezleconstater, laclassebasic_filebufestsemblablelaclassebasic_stringbuf.
Outrelesdclarationsdetypesetcellesduconstructeuretdudestructeur,elledfinittroismthodes
permettantderaliserlesoprationsspcifiquesauxfichiers.
Lamthode open permet,commesonnomlindique,douvrirunfichier.Cettemthodeprendenpa
ramtrelenomdufichierouvrirainsiquelemodedouverture.Cemodepeuttreunecombinaison
logiquedeplusieursconstantesdfiniesdanslaclasseios_base.Cesconstantessontdcritesdansla
288
Chapitre15.Lesfluxdentre/sortie
Section15.3.Lesplusimportantessontin,quipermetdouvrirunfichierenlecture,out,quipermet
delouvrirenlecture, binary,quipermetdelouvrirenmodebinaire, app,quipermetdelouvrir
enmodeajout,et trunc,quipermetdeleviderlorsquilestouvertencriture.Lamthode open
renvoielepointeur this silefichieraputreouvertoulepointeurnuldanslecascontraire.
Laclassebasic_filebufnegrequuneseulepositionpourlalectureetlcrituredanslesfichiers.
Autrementdit, siunfichierestouvertlafoisenlectureetencriture,
lespointeursdelectureet
dcrituredutamponauronttoujourslammevaleur.Lcritureunepositionprovoqueradoncnon
seulement lamodificationdelapositioncouranteencriture, maisgalement celledelaposition
couranteenlecture.
Lamthode close estlamthodeutiliserpourfermerunfichierouvert. Cettemthodenepeut
fonctionnerquesiunfichieresteffectivementouvertdanscetampon.Ellerenvoielepointeur this
silefichiercourantaeffectivementputrefermoulepointeurnulencasderreur.
Enfin,lamthode is_open permetdedterminersiunfichierestouvertounondanscetampon.
Exemple152.Lectureetcrituredansuntampondefichier
#include <iostream>
#include <string>
#include <fstream>
usingnamespacestd;
intmain(void)
{
//Ouvreunfichiertexteetcreuntamponpouryaccder:
filebuffb;
fb.open("test.txt",ios_base::in|ios_base::out|ios_base::trunc);
//Testesilefichierestouvert:
if(fb.is_open())
{
//critdeuxlignes:
stringl1="Bonjour\n";
stringl2="toutlemonde!\n";
fb.sputn(l1.data(),l1.size());
fb.sputn(l2.data(),l2.size());
//Repositionnelepointeurdefichieraudbut.
//Note:ledplacementsefaitpourlesdeux
//tamponsparcequilnyaquunpointeur
//surlesdonnesdufichier:
fb.pubseekpos(0,ios_base::in|ios_base::out);
//Litlespremireslettresdufichier:
cout << (char)fb.sbumpc() << endl;
cout << (char)fb.sbumpc() << endl;
cout << (char)fb.sbumpc() << endl;
//Fermelefichier:
fb.close();
}
return0;
}
289
Chapitre15.Lesfluxdentre/sortie
15.3.Lesclassesdebasedesflux:ios_baseet
basic_ios
Lesclassesdegestiondesfluxconstituentladeuximehirarchiedeclassesdelabibliothquestan
darddentre/sortie.Bienquedestinesaccderdesmdiasvaris,cesclassesdisposentdune
interfacecommunequipermetdensimplifierlutilisation.Cetteinterfaceestessentiellementdfinie
pardeuxclassesdebasesfondamentales:laclasseios_base, quidfinittouteslesfonctionnalits
template basic_ios,quiregroupe
indpendantesdutypedecaractreutilisparlesflux,etlaclasse
lessentieldesfonctionnalitsdesfluxdentre/sortie.
15.3.1.Laclasseios_base
Laclasseios_baseest uneclasseC++classiquedont touteslesclasses template degestiondes
fluxdentre/sortiedrivent. Cetteclassenefournit, commecestlecasdelaplupartdesclasses
debase,quunnombredefonctionnalitstrsrduit.Enpratique,saprincipaleutilitestdedfinir
plusieursjeuxdeconstantesquisontutilisesparsesclassesdrivespouridentifierlesoptionsdes
diffrentsmodesdefonctionnementdisponibles.Cesconstantesportentunnomstandardismaisleur
typenestpasprcisparlanormeC++.Cependant,leurnature(entire,numration,champdebits)
estimpose,etlesimplmentationsdoiventdfinirun typedef permettantdecrerdesvariablesdu
mmetype.
Laclassedebaseios_baseestdclarecommesuitdanslentte ios :
classios_base
{
//Constructeuretdestructeur:
protected:
ios_base();
public:
~ios_base();
//Classedebasedesexceptionsdesfluxdentre/sortie:
classfailure;
//Classedinitialisationdesobjetsdentre/sortiestandards:
classInit;
//Constantesdedfinitiondesoptionsdeformatage:
typedefT1fmtflags;
staticconstfmtflagsboolalpha;
staticconstfmtflagshex;
staticconstfmtflagsoct;
staticconstfmtflagsdec;
staticconstfmtflagsfixed;
staticconstfmtflagsscientific;
staticconstfmtflagsleft;
staticconstfmtflagsright;
staticconstfmtflagsinternal;
staticconstfmtflagsshowbase;
staticconstfmtflagsshowpoint;
staticconstfmtflagsshowpos;
staticconstfmtflagsuppercase;
staticconstfmtflagsunitbuf;
staticconstfmtflagsskipws;
290
Chapitre15.Lesfluxdentre/sortie
staticconstfmtflagsadjustfield;
staticconstfmtflagsbasefield;
staticconstfmtflagsfloatfield;
//Constantesdesmodesdouverturedesfluxetdesfichiers:
typedefT3openmode;
staticconstopenmodein;
staticconstopenmodeout;
staticconstopenmodebinary;
staticconstopenmodetrunc;
staticconstopenmodeapp;
staticconstopenmodeate;
//Constantesdedfinitiondesmodesdepositionnement:
typedefT4seekdir;
staticconstseekdirbeg;
staticconstseekdircur;
staticconstseekdirend;
//Constantesdtatdesfluxdentre/sortie:
typedefT2iostate;
staticconstiostategoodbit;
staticconstiostateeofbit;
staticconstiostatefailbit;
staticconstiostatebadbit;
//Accesseurssurlesoptionsdeformatage:
fmtflagsflags()const;
fmtflagsflags(fmtflagsfmtfl);
fmtflagssetf(fmtflagsfmtfl);
fmtflagssetf(fmtflagsfmtfl,fmtflagsmask);
voidunsetf(fmtflagsmask);
streamsizeprecision()const;
streamsizeprecision(streamsizeprec);
streamsizewidth()const;
streamsizewidth(streamsizewide);
//Mthodedesynchronisation:
staticboolsync_with_stdio(boolsync=true);
//Mthodedenregistrementdescallbackpourlesvnements:
enumevent{erase_event,imbue_event,copyfmt_event};
typedefvoid(*event_callback)(event,ios_base&,intindex);
voidregister_callback(event_call_backfn,intindex);
//Mthodedegestiondesdonnesprives:
staticintxalloc();
long&iword(intindex);
void*&pword(intindex);
//Mthodesdegestiondeslocales:
localeimbue(constlocale&loc);
localegetloc()const;
};
291
Chapitre15.Lesfluxdentre/sortie
Commevouspouvezleconstater,leconstructeurdelaclasseios_baseestdclarenzoneprotge.
Ilnestdoncpaspossibledinstancierunobjetdecetteclasse,
cequiestnormalpuisquellenest
destinequtrelaclassedebasedeclassesplusspcialises.
Lepremierjeudeconstantesdfiniparlaclasseios_basecontienttouteslesvaleursdetypefmtflags,
quipermettentdespcifierlesdiffrentesoptionsutiliserpourleformatagedesdonnescritesdans
lesflux.Cetypedoitobligatoirementtreunchampdebits.Lesconstantesquantellespermettent
dedfinirlabasedenumrotationutilise,sicellecidoittreindiqueavecchaquenombreounon,
ainsiquelesdiffrentesoptionsdeformatageutiliser. Lasignificationprcisedechacunedeces
constantesestdonnedansletableausuivant:
Tableau151.Optionsdeformatagedesflux
Constante
292
Signification
boolalpha
Permetderaliserlesentres/sortiesdesboolenssousformetextuelleetnon
sousformenumrique.Ainsi,lesvaleurs true et false nesontpascritesou
luessouslaformede 0 oude 1,maissouslaformefixeparlaclassede
localisationutiliseparleflux.Pardfaut,lesboolenssontreprsentsparles
chanesdecaractrestrueetfalselorsqueceflagestactif.Cependant,il
estpossibledemodifierceschanesdecaractresendfinissantunelocale
spcifique.LesnotionsdelocalesserontdcritesdansleChapitre16.
hex
Permetderaliserlesentres/sortiesdesentiersenbasehexadcimale.
oct
Permetderaliserlesentres/sortiesdesentiersenbaseoctale.
dec
Permetderaliserlesentres/sortiesdesentiersendcimal.
fixed
Activelareprsentationenvirgulefixedesnombresvirguleflottante.
scientific
Activelareprsentationenvirguleflottantedesnombresvirguleflottante.
left
Utiliselalignementgauchepourlesdonnescritessurlesfluxdesortie.
Danslecasolalargeurdeschampsestfixe,descaractresderemplissage
sontajoutsladroitedecesdonnespouratteindrecettelargeur.
right
Utiliselalignementdroitepourlesdonnescritessurlesfluxdesortie.
Danslecasolalargeurdeschampsestfixe,descaractresderemplissage
sontajoutslagauchedecesdonnespouratteindrecettelargeur.
internal
Effectueunremplissageaveclescaractresderemplissageunepositionfixe
dtermineparlalocaleencoursdutilisationsilalargeurdesdonnesest
infrieurelalargeurdeschampsutiliser.Silapositionderemplissagenest
passpcifieparlalocalepourloprationencours,lecomportementadopt
estlalignementdroite.
showbase
Prciselabaseutilisepourleformatagedesnombresentiers.
showpoint
critsystmatiquementlesparateurdelavirguledansleformatagedes
nombresvirguleflottante,quelapartiefractionnairedecesnombressoit
nulleounon.Lecaractreutilispourreprsentercesparateurestdfinidans
lalocaleutiliseparlefluxdentre/sortie.Lanotiondelocaleseravuedans
leChapitre16.Pardfaut,lecaractreutilisestlepointdcimal(.).
showpos
Utilisesystmatiquementlesignedesnombrescritssurlefluxdesortie,
quilssoientpositifsoungatifs.Leformatagedusignedesnombresefait
selonlescritresdfinisparlalocaleactivepourceflux.Pardfaut,les
nombresngatifssontprfixsdusymbole etlesnombrespositifsdu
symbole +sicetteoptionestactive.Danslecascontraire,lesignedes
nombrespositifsnestpascrit.
Chapitre15.Lesfluxdentre/sortie
Constante
Signification
uppercase
edelexposant
Permetdcrireenmajusculecertainscaractres,commele
desnombresvirguleflottanteparexemple,ouleschiffreshexadcimaux A
F.
unitbuf
Permetdeffectuerautomatiquementuneoprationdesynchronisationdu
cacheutilisparlefluxdesortieaprschaquecriture.
skipws
Permetdignorerlesblancsprcdantlesdonnesliredanslesoprations
dentrepourlesquellesdetelsblancssontsignificatifs.
Signification
in
Permetdouvrirlefluxencriture.
out
Permetdouvrirlefluxenlecture.
binary
Permetdouvrirlefluxenmodebinaire,pourlessystmesquifontune
distinctionentrelesfichierstextesetlesfichiersbinaires.Ceflagnestpas
ncessairepourlessystmesdexploitationconformeslanormePOSIX.
Cependant,ilestprfrabledelutiliserlorsdelouverturedefichiersbinaires
silonveutqueleprogrammesoitportablesurlesautressystmes
dexploitation.
trunc
Permetdeviderautomatiquementlefichierlorsquuneouvertureencritureest
demande.
app
Permetdouvrirlefichierenmodeajoutlorsquuneouvertureencritureest
demande.Danscemode,lepointeurdefichierestsystmatiquement
positionnenfindefichieravantchaquecriture.Ainsi,lescrituressefontles
uneslasuitedesautres,toujourslafindufichier,etquellesquesoientles
oprationsquipeuventavoirlieusurlefichierentretemps.
ate
Permetdouvrirlefichierencritureetdepositionnerlepointeurdefichierla
findeceluici.Notezquecemodedefonctionnementsedistinguedumode
app parlefaitquesiunrepositionnementalieuentredeuxcrituresla
deuximecritureneseferapasforcmentlafindufichier.
293
Chapitre15.Lesfluxdentre/sortie
Tableau153.Directionsdedplacementdansunfichier
Constante
Signification
beg
Ledplacementdefaitparrapportaudbutdufichier.Ledcalagespcifi
danslesfonctionsderepositionnementdoittrepositifounul,lavaleur0
correspondantaudbutdufichier.
cur
Ledplacementsefaitrelativementlapositioncourante.Ledcalagespcifi
danslesfonctionsderepositionnementpeutdonctrengatif,positifounul
(auquelcasaucundplacementnesteffectu).
end
Ledplacementsefaitrelativementlafindufichier.Ledcalagefournidans
lesfonctionsderepositionnementdoittrepositifounul,lavaleur0
correspondantlafindefichier.
Signification
goodbit
Cetteconstantecorrespondltatnormalduflux,lorsquilnesestproduit
aucuneerreur.
eofbit
Cebitestpositionndanslavariabledtatdufluxlorsquelafindufluxat
atteinte,soitparcequilnyaplusdedonneslire,soitparcequonnepeut
plusencrire.
failbit
Cebitestpositionndanslavariabledtatdufluxlorsquuneerreurlogique
sestproduitelorsduneoprationdelectureoudcriture.Cecipeutavoirlieu
lorsquelesdonnescritesouluessontincorrectes.
badbit
Cebitestpositionnlorsquuneerreurfatalesestproduite.Cegenrede
situationpeutseproduirelorsquuneerreuraeulieuauniveaumatriel
(secteurdfectueuxdundisqueduroucoupurerseauparexemple).
294
Chapitre15.Lesfluxdentre/sortie
desconversionsdesnombreslorsdescritures.
Laplupartdesoptionsquelonpeutfixersontpermanentes,cestdirequellesrestentactivesjus
qucequonspcifiedenouvellesoptions.Cependant,cenestpaslecasduparamtredelargeur
quelonrenseignegrcelamthode width. Eneffet, chaqueoprationdcriturerinitialisece
paramtrelavaleur0.Ilfautdoncspcifierlalargeurminimalepourchaquedonnecritesurle
flux.
Exemple153.Modificationdesoptionsdeformatagedesflux
#include <iostream>
usingnamespacestd;
//Afficheunboolen,unnombreentieretunnombrevirgule:
voidprint(boolb,inti,floatf)
{
cout << b << "" << i << "" << f << endl;
}
intmain(void)
{
//Afficheaveclesoptionspardfaut:
print(true,35,3105367.9751447);
//Passeenhexadcimal:
cout.unsetf(ios_base::dec);
cout.setf(ios_base::hex);
print(true,35,3105367.9751447);
//Affichelabasedesnombreset
//affichelesboolenstextuellement:
cout.setf(ios_base::boolalpha);
cout.setf(ios_base::showbase);
print(true,35,3105367.9751447);
//Afficheunflottantennotationvirgulefixe
//avecunelargeurminimalede16caractres:
cout << "***";
cout.width(16);
cout.setf(ios_base::fixed,ios_base::floatfield);
cout << 315367.9751447;
cout << "***" << endl;
//Recommenceenfixantlaprcision
//3chiffresetlalargeur10caractres:
cout << "***";
cout.precision(3);
cout.width(10);
cout << 315367.9751447;
cout << "***" << endl;
return0;
}
Note:Onprendrabiengardeaufaitquelalargeurdeschampsdanslesquelslesdonnessont
critesestunelargeurminimale,pasunelargeurmaximale.Enparticulier,celasignigiequeles
crituresnesontpastronquessiellessontplusgrandequecettelargeur.Ondevradoncfaire
extrmementattentionnepasprovoquerdedbordementslorsdescritures.
Onnoublierapasdesassurerdelacohrencedesparamtresdufluxlorsquonmodifielavaleur
duneoption.Parexemple,danslexempleprcdent,ilfautdsactiverlemploi delanumrota
tiondcimalelorsquelondemandeutiliserlabasehexadcimale.Cetteoprationatfaite
295
Chapitre15.Lesfluxdentre/sortie
explicitementici pourbienmontrersonimportance,maiselleauraitgalementputreralise
parlemploidunmasqueaveclaconstante ios_base::basefield .Lexempleprcdentmon
trecommentutiliserunmasqueaveclappel setf pourfixerlareprsentationdesnombres
virgule.
Laclasseios_basefournitgalementuncertainnombredeservicesgnrauxauprogrammeuret
sesclassesdrives.Lamthode sync_with_stdio permetdedterminer,pourunfluxdentre/
sortiestandard,silestsynchronisaveclefluxsousjacentousidesdonnessetrouventencoredans
sontampon.Lorsquelleestappeleavecleparamtre false dsledbutduprogramme,ellepermet
dedcorrlerlefonctionnementdufluxC++etdufluxstandardsousjacent.Pourtouslesautresap
pels,cettemthodeignoreleparamtrequiluiestfourni.Lamthode register_callback permet
denregistrerunefonctionderappelquiseraappeleparlaclasseios_baselorsquedesvnements
susceptiblesdemodifiernotablementlecomportementdufluxseproduisent.Cesfonctionsderappel
peuventrecevoirunevaleurentireenparamtrequipeuttreutilisepourrfrencerdesdonnes
privescontenantdesparamtrespluscomplexes.Lesmthodesxalloc, iword et pword sontfour
niesafindepermettredestockercesdonnespriveset delesretrouverfacilement laidedun
indice,quipeuttrelavaleurpasseenparamtrelafonctionderappel.Cesmthodespermettent
dercuprerdesrfrencessurdesvaleursdetypelongetsurdespointeursdetypevoid.Enfin,la
classeios_basefournituneclassedebasepourlesexceptionsquelesclassesdefluxpourrontutiliser
cin, cout, cerr, clog et
afindesignaleruneerreuretuneclassepermettantdinitialiserlesobjets
leurssemblablespourlescaractreslarges.Toutescesfonctionnalitsnesontgnralementpasdune
trsgrandeutilitpourlesprogrammeursetsontenralitfourniepourfaciliterlimplmentationdes
classesdefluxdelabibliothquestandard.
Enfin, laclasseios_basefournitlesmthodes getloc et imbue quipermettentrespectivementde
rcuprerlalocaleutiliseparlefluxet
denfixeruneautre. Cettelocaleest utiliseparleflux
pourdterminerlamaniredereprsenteretdelirelesnombresetpoureffectuerlesentres/sorties
formatesenfonctiondesparamtresdelangueetdesconventionslocalesdupaysoleprogramme
est excut. Lesnotionsdelocaleet deparamtresinternationauxseront dcritsendtail dansle
Chapitre16.
15.3.2.Laclassebasic_ios
Laclasse template basic_iosfournittouteslesfonctionnalitscommunestouteslesclassesde
fluxdelabibliothquedentre/sortie.Cetteclassedrivedelaclasseios_baseetapportetousles
mcanismesdegestiondestamponspourlesclassesdeflux.Laclassebasic_iosestdclarecomme
suitdanslentte ios :
template <classcharT,
classtraits=char_traits
<charT>>
classbasic_ios:publicios_base
{
//Constructeuretdestructeur:
protected:
basic_ios();
voidinit(basic_streambuf
<charT,traits> *flux);
public:
//Typesdedonnes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
296
Chapitre15.Lesfluxdentre/sortie
typedeftypenametraits::off_typeoff_type;
typedeftraits
traits_type;
//Constructeurpublique,destructeuretoprationdecopie:
explicitbasic_ios(basic_streambuf
<charT,traits> *flux);
virtual~basic_ios();
basic_ios©fmt(constbasic_ios&);
//Mthodesdegestiondestampons:
basic_streambuf<charT,traits> *rdbuf()const;
basic_streambuf<charT,traits> *rdbuf(
basic_streambuf<charT,traits> *tampon);
//Mthodesdegestiondesexceptions:
iostateexceptions()const;
voidexceptions(iostateexcept);
//Accesseurs:
operatorvoid*()const
booloperator!()const
iostaterdstate()const;
voidclear(iostatestatut=goodbit);
voidsetstate(iostatestatut);
boolgood()const;
booleof() const;
boolfail()const;
boolbad() const;
char_typefill()const;
char_typefill(char_typec);
basic_ostream<charT,traits> *tie()const;
basic_ostream<charT,traits> *tie(
basic_ostream<charT,traits> *flux);
//Mthodesdegestiondeslocales:
localeimbue(constlocale&loc);
char
narrow(char_typec,chardefaut)const;
char_typewiden(charc)const;
};
Leconstructeurdebaseainsiquelamthode init,destineassocieruntamponunfluxaprssa
construction,sontdclarsenzoneprotge.Ainsi,ilnestpaspossibledinstancieretdinitialiser
manuellementunfluxavecuntampon.Cependant,laclassebasic_iosfournitunconstructeurenzone
publiquequi permet decrerunnouveaufluxet delinitialiserlavole. Ceconstructeurprend
enparamtreladresseduntamponquiseraassociaufluxaprslaconstruction.Remarquezque,
bienquil soit ainsi parfaitement possibledinstancierunobjet detypelunedesinstancesdela
classe template basic_ios,celanapasgrandintrt.Eneffet,cetteclassenefournitpasassezde
fonctionnalitspourraliserdesentres/sortiesfacilementsurleflux.Laclassebasic_iosestdonc
rellementdestinetreutiliseentantqueclassedebasepourdesclassesplusspcialisesdans
lesoprationsdentre/sortie.
Unefoisinitialiss,lesfluxsontassocisauxtamponsgrceauxquelsilsaccdentauxmdiasphy
siquespourleursoprationsdentre/sortie. Cependant, cetteassociationnestpasfigeetilest
possibledechangerdetamponaposteriori. Lesmanipulationsdetamponsonteffectuesavecles
deuxsurchargesdelamthode rdbuf.Lapremirepermetdercuprerladressedelobjettampon
297
Chapitre15.Lesfluxdentre/sortie
courantetladeuximedenspcifierunnouveau.Cettederniremthoderenvoieladressedutampon
prcdent.Bienentendu,lefaitdechangerletampondunfluxprovoquesarinitialisation.
Lesfluxdelabibliothquestandardpeuventsignalerlescasderreursauxfonctionsquilesutilisentde
diffrentesmanires.Lapremireestsimplementderenvoyeruncodederreur(false oulecaractre
defindefichier),etladeuximeestdelanceruneexceptiondrivedelaclassedexceptionfailure
(dfiniedanslaclassedebaseios_base). Cecomportementestparamtrableenfonctiondestypes
derreursquipeuventseproduire.Pardfaut,lesclassesdefluxnutilisentpaslesexceptions,quelles
quesoientleserreursrencontres. Toutefois, ilestpossibledactiverlemcanismedesexceptions
individuellementpourchaquetypederreurpossible.Laclassebasic_iosgrepourcelaunmasque
dexceptionsquipeuttrercupretmodifilaidededeuxmthodessurcharges.Cesmthodes
sontlesmthodes exceptions.Lapremireversionrenvoielemasquecourantetladeuximepermet
defixerunnouveaumasque.Lesmasquesdexceptionssontconstitusdecombinaisonslogiquesdes
bitsdtatdesfluxdfinisdanslaclasseios_base(savoirgoodbit, eofbit, failbit et badbit).
Lefaitdechangerlemasquedexceptionsrinitialiseltatduflux.
Laclassebasic_iosfournitgalementtoutunensembledaccesseursgrceauxquelsilestpossiblede
rcuprerltatcourantduflux.Cesaccesseurssontprincipalementdestinsfaciliterlamanipulation
dufluxetsimplifierlesdiffrentesexpressionsdanslesquellesilestutilis.Parexemple,loprateur
detranstypageversletypepointeursurvoidpermetdetesterlavaliditdufluxcommesilsagissait
dunpointeur.Cetoprateurretourneeneffetunevaleurnonnullesilefluxestutilisable(cestdire
silamthode fail renvoie false.Demme,loprateurdengation operator! renvoielamme
valeurquelamthode fail.
Commevouslaurezsansdoutecompris, lamthode fail indiquesi leflux(et doncletampon
true dsquelun
contrlparceflux)estdansuntatcorrect.Enpratique,cettemthoderenvoie
desbits ios_base::failbit ou ios_base::badbit estpositionndanslavariabledtatduflux.
Vouspourrezfaireladistinctionentrecesdeuxbitsgrcelamthode bad,quiellenerenvoie true
quesilebit ios_base::badbit estpositionn. Lesautresmthodesdelecturedeltatduflux
portentdesnomsexplicitesetleursignificationnedoitpasposerdeproblme.Onprendratoutefois
gardebiendistinguerlamthode clear,quipermetderinitialiserltatdufluxaveclemasquede
bitspassenparamtre,delamthode setstate,quipermetdepositionnerunbitcomplmentaire.
Cesdeuxmthodessontsusceptiblesdelancerdesexceptionssilenouveltatdufluxlerequiertetsi
sonmasquedexceptionslexige.
Ledernieraccesseurutilepourleprogrammeurestlaccesseur fill. Cetaccesseurpermetdelire
lavaleurducaractrederemplissageutilislorsquelalargeurdeschampsestsuprieurelalargeur
desdonnesqui doivent trecritessurlefluxdesortie. Pardfaut, cecaractreest lecaractre
despacement.
Note:Lesdeuxsurchargesdelamthodetie permettentdestockerdanslefluxunpointeursur
unfluxdesortiestandardaveclequellesoprationsdentre/sortiedoiventtresynchronises.
Cesmthodessontutiliseseninterneparlesmthodesdentre/sortiedesclassesdrives
delaclassebasic_iosetnesontpasrellementutilespourlesprogrammeurs.Engnraldonc,
seulelesclassesdelabibliothquestandardlesappelleront.
Enfin,laclassebasic_iosprendgalementencomptelalocaledufluxdanstoussestraitements.Elle
redfinitdonclamthode imbue afindepouvoirdtecterleschangementdelocalequelutilisateur
peutfaire.Bienentendu,lamthode getloc esthritedelaclassedebaseios_baseetpermettou
joursdercuprerlalocalecourante.Deplus,laclassebasic_iosdfinitdeuxmthodespermettant
deraliserlesconversionsentreletypedecaractrecharetletypedecaractrefournienparamtre
template.Lamthode widen permet,commesonnomlindique,deconvertiruncaractredetype
char enuncaractredutype template duflux.Inversement,lamthodenarrow permetdeconver
298
Chapitre15.Lesfluxdentre/sortie
tiruncaractredutypedecaractredufluxenuncaractredetypechar.
Cettemthodeprenden
paramtrelecaractreconvertiretlavaleurpardfautquedoitprendrelersultatencasdchecde
laconversion.
15.4.Lesfluxdentre/sortie
Laplupart desfonctionnalitsdesfluxdentre/ sortiesont implmentesauniveaudesclasses
template basic_ostreametbasic_istream.Cesclassesdriventtoutesdeuxdirectementdelaclasse
basic_ios,dontelleshritentdetouteslesfonctionnalitsdegestiondestamponsetdegestiondtat.
Lesclassesbasic_ostreametbasic_istreamserontsansdoutelesclassesdefluxquevousutiliserezle
plussouvent,carcestleurniveauquesontdfiniestouteslesfonctionnalitsdelectureetdcriture
surlesflux,aussibienpourlesdonnesformatestellesquelesentiers,lesflottantsouleschanesde
caractres,quepourlescrituresdedonnesbrutes.Deplus,lesfluxdentre/sortiestandards cin,
cout, cerr et clog sonttousdesinstancesdecesclasses.
Labibliothquestandarddfinitgalementuneclassecapablederaliserlafoislesoprationsde
lectureetdcrituresurlesflux:laclassebasic_iostream.Enfait,cetteclassedrivesimplementdes
deuxclassesbasic_istreametbasic_ostream,etregroupedonctouteslesfonctionnalitsdecesdeux
classes.
15.4.1.Laclassedebasebasic_ostream
Laclassebasic_ostreamfournittouteslesfonctionspermettantdeffectuerdescrituressurunflux
desortie, quecescrituressoient formatesounon. Elleest dclarecommesuit danslentte
ostream :
template <classcharT,
classtraits=char_traits
<charT>>
classbasic_ostream:virtualpublicbasic_ios<charT,traits>
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
typedeftraits
traits_type;
//Leconstructeuretledestructeur:
explicitbasic_ostream(basic_streambuf
<char_type,traits> *tampon);
virtual~basic_ostream();
//Lesoprationsdcrituresformates:
basic_ostream<charT,traits> &operator<<(bool);
basic_ostream<charT,traits> &operator<<(short);
basic_ostream<charT,traits> &operator<<(unsignedshort);
basic_ostream<charT,traits> &operator<<(int);
basic_ostream<charT,traits> &operator<<(unsignedint);
basic_ostream<charT,traits> &operator<<(long);
basic_ostream<charT,traits> &operator<<(unsignedlong);
basic_ostream<charT,traits> &operator<<(float);
basic_ostream<charT,traits> &operator<<(double);
299
Chapitre15.Lesfluxdentre/sortie
basic_ostream<charT,traits> &operator<<(longdouble);
basic_ostream<charT,traits> &operator<<(void*);
basic_ostream<charT,traits> &operator<<
(basic_streambuf<char_type,traits> *tampon);
//Classedegestiondesexceptionspourlesoprateursdcrituresformates:
classsentry
{
public:
explicitsentry(basic_ostream
<charT,traits> &);
~sentry();
operatorbool();
};
//Lesoprationsdcrituresnonformates:
basic_ostream<charT,traits> &put(char_type);
basic_ostream<charT,traits> &write(constchar_type*p,streamsizetaille);
//Lesoprationsdegestiondutampon:
basic_ostream<charT,traits> &flush();
pos_typetellp();
basic_ostream<charT,traits> &seekp(pos_type);
basic_ostream<charT,traits> &seekp(off_type,ios_base::seekdir);
//Lesoprationsdegestiondesmanipulateurs:
basic_ostream<charT,traits> &operator<<
(basic_ostream<charT,traits> &(*pf)(
basic_ostream<charT,traits> &));
basic_ostream<charT,traits> &operator<<
(basic_ios<charT,traits> &(*pf)(basic_ios <charT,traits> &));
basic_ostream<charT,traits> &operator<<
(ios_base&(*pf)(ios_base&));
};
Commevouspouvezleconstater, leconstructeurdecetteclasseprendenparamtreunpointeur
surlobjettampondanslequellescrituresdevronttreralises. Vouspouvezdoncconstruireun
fluxdesortiepartirdenimportequeltampon,simplementenfournissantcetamponenparamtre
auconstructeur. Cependant, ilnefautpasprocderainsiengnral, maisutiliserpluttlesclasses
drivesdelaclassebasic_ostreametspcialisesdanslescrituressurfichiersetdansdeschanes
decaractres.
Lescrituresformatessont ralisesparlintermdiairedediffrentessurchargesdeloprateur
dinsertion operator<<,dontilexisteuneversionpourchaquetypededonnedebasedulangage.
Ainsi,lcrituredunevaleurdanslefluxdesortiesefaitextrmementsimplement:
//crituredunechanedecaractressurlefluxdesortiestandard:
cout << "Voicilavaleurdunentier:\n";
//crituredunentiersurlefluxdesortiestandard: