Beruflich Dokumente
Kultur Dokumente
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:
cout << 45;
300
exactement dela
Chapitre15.Lesfluxdentre/sortie
Note:Lesoprationsdeformatageprennentencomptetouteslesoptionsdeformatagequisont
stockesdanslaclassedebaseios_base.Engnral,lesoprationsdcriturenemodifientpas
cesoptions.Toutefois,lalargeurminimaledeschampsdanslesquelslesrsultatssontformats
estsystmatiquementrinitialise0aprschaquecriture.Ilestdoncncessaire,lorsquelon
raliseplusieurscrituresformatesdansunfluxdesortie,despcifierpourchaquevaleursa
largeurminimalesiellenedoitpastregale0.Autrementdit,ilfautredirelalargeurdechaque
champ,mmesilsutilisenttouslammelargeurminimale.
Lesoprationsdeformatageutilisentgalementlesconventionslocalesdupaysoleprogramme
estexcut,conventionsquisontdfiniesdanslalocaleinclusedanslefluxdesortie.Lesnotions
delocaleserontdtaillesdansleChapitre16.
Bienentendu, ilestpossiblededfinirdenouvellessurchargesdeloprateurdinsertionpourles
typesdfinisparlutilisateur, cequipermetdtendrelinfinilespossibilitsdecetteclasse.
Ces
surchargesdevrontobligatoirementtredfinieslextrieurdelaclasse template basic_ostream
template
et,silonveutlescriredemaniregnrique,ellesdevrontgalementtredesfonctions
paramtresparletypedecaractredufluxsurlequelellestravaillent.
Vousnoterezlaprsenceduneclassesentrydanslaclassebasic_ostream.Cetteclasseestuneclasse
utilitairepermettantderaliserlesinitialisationsquidoiventprcdertouteslesoprationsdcriture
auseindessurchargesdeloprateurdinsertion. Entreautresoprations, leconstructeurdecette
tie
classepeut synchroniserlefluxdesortiestandardencapsuldanslefluxgrcelamthode
delaclassedebasebasic_ios, et prendretouteslesmesuresdevant prcderlescrituressurle
flux.Vousdevrezdonctoujoursutiliserunobjetlocaldecetypelorsquevouscrirezunesurcharge
deloprateur operator<< pourvosproprestypes. Lescrituresnedevronttreralisesquesi
linitialisationarussi,cequipeuttrevrifisimplementencomparantlobjetlocaldetypesentry
aveclavaleur true.
Exemple154.Dfinitiondunnouveloprateurdinsertionpourunfluxdesortie
#include <iostream>
#include <string>
usingnamespacestd;
//Dfinitionduntypededonnepriv:
structPersonne
{
stringNom;
stringPrenom;
intAge;
//Encentimtres.
intTaille;
};
//Dfinitiondeloprateurdcriturepourcetype:
template <classcharT,classTraits
>
basic_ostream<charT,Traits> &operator<<(
basic_ostream<charT,Traits> &flux,
constPersonne&p)
{
//Inialisationdufluxdesortie:
typenamebasic_ostream<charT,Traits>::sentryinit(flux);
if(init)
{
//crituredesdonnes:
301
Chapitre15.Lesfluxdentre/sortie
intMetres=p.Taille/100;
intReste=p.Taille%100;
flux << p.Prenom << "" << p.Nom <<
"mesure" << Metres <<
"m" << Reste << "(" <<
p.Age << "an";
if(p.Age > 1)flux << "s";
flux << ")";
}
returnflux;
}
intmain(void)
{
//Construitunenouvellepersonne:
Personnep;
p.Nom="Dupont";
p.Prenom="Jean";
p.Age=28;
p.Taille=185;
//Affichelescaractristiquesdecettepersonne:
cout << p << endl;
return0;
}
Note:Lutilisationdelobjetlocal detypesentrycommeunboolenestautoriseparcequela
classesentrydfinitunoprateurdetranstypageversletypebool.
Leconstructeurdelaclassesentryestsusceptibledelancerdesexceptions,selonlaconfigura
tiondumasquedexceptionsdufluxdesortieaveclequelonlinitialise.
Lescrituresdedonnesbrutesnedisposentbienentendupasdesurchargespourchaquetypede
donne,puisquilsagitdanscecasdcrirelesdonnesdirectementsurlefluxdesortie,sanslesfor
matersousformetextuelle.Cescrituressontdoncralisesparlintermdiairedemthodesddies
qui effectuent soit lcritureduncaractreunique, soit lcritureduntableaudecaractrescom
plet.Pourcrireununiquecaractresurlefluxdesortie,vouspouvezutiliserlamthode put.Pour
lcrituredunblocdedonnesenrevanche,ilfaututiliserlamthode write,quiprendenparamtre
unpointeursurlazonededonnescrireetlatailledecettezone.
Exemple155.criturededonnesbrutessurunfluxdesortie
#include <iostream>
usingnamespacestd;
//Dfinitiondequelquescodesdecouleurs
//pourlesterminauxANSI:
constcharRouge[]={033,[,3,1,m};
constcharVert[]={033,[,3,2,m};
constcharJaune[]={033,[,3,3,m};
constcharReset[]={033,[,m,017};
intmain(void)
{
//crituredunmessagecolor:
cout.write(Rouge,sizeof(Rouge));
302
Chapitre15.Lesfluxdentre/sortie
cout << "Bonjour";
cout.write(Vert,sizeof(Vert));
cout << "tout";
cout.write(Jaune,sizeof(Jaune));
cout << "lemonde!" << endl;
cout.write(Reset,sizeof(Reset));
return0;
}
Bienentendu,laclassebasic_ostreamfournitlesmthodesncessaireslagestiondutamponsous
jacent.Lamthode flush permetdesynchroniserletamponutilisparleflux(enappelantlamthode
pubsync decedernier).Lamthode tellp permetdelirelapositioncourantedanslefluxdesortie,
etlesdeuxsurchargesdelamthode seekp permettentdemodifiercettepositionsoitdemanire
absolue,soitdemanirerelativelapositioncourante.Nousverronsunexempledutilisationdeces
mthodesdansladescriptiondesclassesdefluxpourlesfichiers.
Laclassebasic_ostreamdfinit galement dessurchargesdeloprateur dinsertioncapablesde
prendreenparamtredespointeursdefonctions. Cesmthodesneconstituent pasdesoprations
dcritureproprementparler,maispermettentderaliserdesoprationssurlesfluxdesortieplus
facilementlaidedefonctionscapablesdelesmanipuler.Enraisondecetteproprit,cesfonctions
sontcourammentappelesdesmanipulateurs.Enralit,cesmanipulateursnesontriendautreque
desfonctionsprenant unfluxenparamtreet ralisant desoprationssurceflux. Lesoprateurs
operator<< prenant enparamtrecesmanipulateurslesexcutent
sur lobjet courant *this.
Ainsi,ilestpossibledappliquercesmanipulateursunfluxsimplementenralisantunecrituredu
manipulateursurceflux,exactementcommepourlescrituresnormales.
Labibliothquestandarddfinit tout unjeudemanipulateursextrmement utilespourdfinirles
optionsdeformatageetpoureffectuerdesoprationsdebasesurlesflux.Grcecesmanipulateurs,
ilnestplusncessairedutiliserlamthode setf delaclasseios_baseparexemple.Parexemple,le
symbole endl utilispoureffectuerunretourlalignedanslesoprationsdcrituresurlesfluxde
sortienestriendautrequunmanipulateur,dontladclarationestlasuivante:
template <classcharT,classTraits
>
basic_ostream<charT,Traits> &endl(
basic_ostream<charT,Traits> &flux);
etdontlerleestsimplementdcrirelecaractrederetourlaligneetdappelerlamthode flush
dufluxdesortie.
Ilexistedesmanipulateurspermettantdetravaillersurlaclassedebaseios_baseousursesclasses
drivescommelaclassebasic_ostreamparexemple, dolaprsencedeplusieurssurchargesde
loprateurdinsertionpourcesdiffrentsmanipulateurs.Ilexistegalementdesmanipulateurspre
nantdesparamtresetrenvoyantuntypededonnesspcialpourlequelunoprateurdcritureat
dfini,etquipermettentderaliserdesoprationspluscomplexesncessitantdesparamtrescom
plmentaires.Lesmanipulateurssontdfinis,selonleurnature,soitdanslenttededclarationdu
flux,soitdanslentte ios,soitdanslentte iomanip.
Letableausuivantprsentelesmanipulateurslesplussimplesquineprennentpasdeparamtre:
Tableau155.Manipulateursdesfluxdesortie
Manipulateur
Fonction
endl
Envoieuncaractrederetourlalignesurlefluxetsynchroniseletamponpar
unappellamthode flush.
ends
Envoieuncaractrenulterminaldefindelignesurleflux.
303
Chapitre15.Lesfluxdentre/sortie
Manipulateur
Fonction
flush
Synchroniseletamponutilisparlefluxparunappellelamthode
boolalpha
flush.
Activeleformatagedesboolenssousformetextuelle.
noboolalpha
Dsactiveleformatagetextueldesboolens.
hex
Formatelesnombresenbase16.
oct
Formatelesnombresenbase8.
dec
Formatelesnombresenbase10.
fixed
Utiliselanotationenvirgulefixepourlesnombresvirgule.
scientific
Utiliselanotationenvirguleflottantepourlesnombresvirgule.
left
Alignelesrsultatsgauche.
right
Alignelesrsultatsdroite.
internal
Utiliseleremplissagedeschampsavecdesespacescomplmentairesune
positionfixedtermineparlalocalecourante.quivalent right silalocale
nespcifieaucunepositionderemplissageparticulire.
showbase
Indiquelabasedenumrotationutilise.
noshowbase
Nindiquepaslabasedenumrotationutilise.
showpoint
Utiliselesparateurdevirguledanslesnombresvirgule,mmesilapartie
fractionnaireestnulle.
noshowpoint
Nutiliselesparateurdevirgulequesilapartiefractionnairedesnombres
virguleflottanteestsignificative.
showpos
critsystmatiquementlesignedesnombres,mmesilssontpositifs.
noshowpos
Ncritlesignedesnombresquesilssontngatifs.
uppercase
critlesexposantsetleschiffreshexadcimauxenmajuscule.
nouppercase
critlesexposantsetleschiffreshexadcimauxenminuscule.
unitbuf
Effectueuneoprationdesynchronisationducachegrparletamponduflux
aprschaquecriture.
nounitbuf
Neffectuelesoprationsdesynchronisationducachegrparletampondu
fluxquelorsquecelaestexplicitementdemand.
Lesparamtressuivantssontunpeupluscomplexes,puisquilsprennentdesparamtrescomplmen
taires.Ilsrenvoientuntypededonnespcifiquechaqueimplmentationdelabibliothquestandard
etquinestdestinqutreinsrdansunfluxdesortielaidedeloprateurdinsertion:
Tableau156.Manipulateursutilisantdesparamtres
Manipulateur
304
Fonction
resetiosflags(ios_base::fmtflags)
Permetdeffacercertainsbitsdesoptionsdu
flux.Cesbitssontspcifisparunecombinaison
logiquedeconstantesdetypeios_base::fmtflags.
setiosflags(ios_base::fmtflags)
Permetdepositionnercertainsbitsdesoptions
duflux.Cesbitssontspcifisparune
combinaisonlogiquedeconstantesdetype
ios_base::fmtflags.
Chapitre15.Lesfluxdentre/sortie
Manipulateur
Fonction
setbase(intbase)
Permetdeslectionnerlabasedenumrotation
utilise.Lesvaleursadmissiblessont8,10et16
respectivementpourlabaseoctale,labase
dcimaleetlabasehexadcimale.
setprecision(int)
Permetdespcifierlaprcision(nombrede
caractressignificatifs)desnombresformats.
setw(int)
Permetdespcifierlalargeurminimaledu
champdanslequelladonnesuivanteseracrite
laprochaineoprationdcrituresurleflux.
setfill(char_type)
Permetdespcifierlecaractrederemplissage
utiliserlorsquelalargeurdeschampsest
infrieurelalargeurminimalespcifiedans
lesoptionsdeformatage.
Exemple156.Utilisationdesmanipulateurssurunfluxdesortie
#include <iostream>
#include <iomanip>
usingnamespacestd;
intmain(void)
{
//Affichelesboolenssousformetextuelle:
cout << boolalpha << true << endl;
//critlesnombresenhexadcimal:
cout << hex << 57 << endl;
//Repasseenbase10:
cout << dec << 57 << endl;
//Afficheunflottantavecunelargeur
//minimalede15caractres:
cout << setfill(*) << setw(15) << 3.151592 << endl;
//Recommencemaisavecunalignementgauche:
cout << left << setw(15) << 3.151592 << endl;
}
15.4.2.Laclassedebasebasic_istream
La deuxime classe la plus utilise de la bibliothque dentre / sortie est sans doute la
classe template basic_istream. linstar de la classe ostream, cette classe fournit toutes
lesfonctionnalitsdelecturededonnesformatesounonpartir
duntampon. Cesont donc
certainementlesmthodescetteclassequevousutiliserezleplussouventlorsquevousdsirerezlire
lesdonnesdunflux.Laclassebasic_istreamestdclarecommesuitdanslentteistream :
template <classcharT,
classtraits=char_traits
<charT>>
classbasic_istream:virtualpublicbasic_ios<charT,traits>
{
public:
305
Chapitre15.Lesfluxdentre/sortie
//Lestypesdedonnes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
typedeftraits
traits_type;
//Leconstructeuretdestructeur:
explicitbasic_istream(basic_streambuf
<charT,traits> *sb);
virtual~basic_istream();
//Lesoprationdegestiondesentresformates:
basic_istream<charT,traits> &operator>>(bool&n);
basic_istream<charT,traits> &operator>>(short&n);
basic_istream<charT,traits> &operator>>(unsignedshort&n);
basic_istream<charT,traits> &operator>>(int&n);
basic_istream<charT,traits> &operator>>(unsignedint&n);
basic_istream<charT,traits> &operator>>(long&n);
basic_istream<charT,traits> &operator>>(unsignedlong&n);
basic_istream<charT,traits> &operator>>(float&f);
basic_istream<charT,traits> &operator>>(double&f);
basic_istream<charT,traits> &operator>>(longdouble&f);
basic_istream<charT,traits> &operator>>(void*&p);
basic_istream<charT,traits> &operator>>
(basic_streambuf<char_type,traits> *sb);
//Classedegestiondesexceptionspourlesoprateursdcrituresformates:
classsentry
{
public:
explicitsentry(basic_istream
<charT,traits> &flux,
boolconserve=false);
~sentry();
operatorbool();
};
//Lesoprationsdelecturedesdonnesbrutes:
int_typeget();
basic_istream<charT,traits> &get(char_type&c);
int_typepeek();
basic_istream<charT,traits> &putback(char_typec);
basic_istream<charT,traits> &unget();
basic_istream<charT,traits> &read(char_type*s,streamsizen);
streamsize
readsome(char_type*s,streamsizen);
basic_istream<charT,traits> &get(char_type*s,streamsizen);
basic_istream<charT,traits> &get(char_type*s,streamsizen,
char_typedelim);
basic_istream<charT,traits> &get(
basic_streambuf<char_type,traits> &sb);
basic_istream<charT,traits> &get(
basic_streambuf<char_type,traits> &sb,char_typedelim);
basic_istream<charT,traits> &getline(char_type*s,streamsizen);
basic_istream<charT,traits> &getline(char_type*s,streamsizen,
char_typedelim);
basic_istream<charT,traits> &ignore
(streamsizen=1,int_typedelim=traits::eof());
306
Chapitre15.Lesfluxdentre/sortie
streamsizegcount()const;
//Lesoprationsdegestiondutampon:
intsync();
pos_typetellg();
basic_istream<charT,traits> &seekg(pos_type);
basic_istream<charT,traits> &seekg(off_type,ios_base::seekdir);
//Lesoprationsdegestiondesmanipulateurs:
basic_istream<charT,traits> &operator>>
(basic_istream<charT,traits> &(*pf)(
basic_istream<charT,traits> &));
basic_istream<charT,traits> &operator>>
(basic_ios<charT,traits> &(*pf)(basic_ios <charT,traits> &));
basic_istream<charT,traits> &operator>>
(ios_base&(*pf)(ios_base&));
};
Toutcommelaclassebasic_ostream,leconstructeurdelaclassebasic_istreamprendenparamtre
unpointeursurlobjetgrantletampondanslequellescrituresdevronttreeffectues.Cependant,
mmesilestpossibledecreruneinstancedefluxdentresimplementlaidedececonstructeur,
celanestpasrecommandpuisquelabibliothquestandardfournitdesclassesspcialisespermet
tantdecrerdesfluxdesortieorientsfichiersouchanesdecaractres.
Lutilisation des diffrentes surcharges de loprateur dextraction des donnes formates
operator>> nedevraitpasposerdeproblme.Lecompilateurdterminelasurchargeutiliseren
fonctiondutypedesdonneslire, dterminparlarfrencedevariablefournieenparamtre.
Cettesurchargercuprealorslesinformationsdansletamponassociauflux,lesinterprteetcrit
lanouvellevaleurdanslavariable.
Bienentendu, tout commepourlaclassebasic_ostream, il est possibledcriredenouvellessur
chargesdeloprateurdextractionafindeprendreenchargedenouveauxtypesdedonnes.Idale
ment,cessurchargesdevronttregalementdesfonctions template paramtresparletypedeca
ractredufluxsurlequelellestravaillent,etellesdevrontgalementutiliseruneclassedinitialisation
sentry.Cetteclasseaprincipalementpourbutdinitialiserlefluxdentre,ventuellementenlesyn
chronisantavecunfluxdesortiestandarddontlaclassebasic_ostreampeuttrestockedansleflux
dentrelaidedelamthode tie delaclassedebasebasic_ios, etensupprimantlesventuels
caractresblancsavantlalecturedesdonnes.
Notezque,contrairementlaclassesentrydesfluxdesortie,leconstructeurdelaclassesentrydes
fluxdentreprendundeuximeparamtre.Ceparamtreestunboolenquiindiquesilescaractres
blancsprsentsdanslefluxdedonnesdoiventtreliminsavantloprationdelectureounon.En
gnral, pourlesoprationsdelectureformates, cesontdescaractresnonsignificatifsetilfaut
effecivementsupprimercescaractres,aussilavaleurspcifierpourcesecondparamtreestelle
false. Commecest aussi lavaleurpardfaut, lamaniredutiliserdelaclassesentrydansles
oprateursdextractioneststrictementidentiquecelledelaclassesentrydesoprateursdinsertion
delaclassebasic_ostream.
Exemple157.crituredunnouveloprateurdextractionpourunfluxdentre
#include <iostream>
#include <string>
307
Chapitre15.Lesfluxdentre/sortie
usingnamespacestd;
//Dfinitionduntypededonnepriv:
structPersonne
{
stringNom;
stringPrenom;
intAge;
//Encentimtres.
intTaille;
};
//Dfinitiondeloprateurdelecturepourcetype:
template <classcharT,classTraits
>
basic_istream<charT,Traits> &operator>>(
basic_istream<charT,Traits> &flux,Personne&p)
{
//Inialisationdufluxdesortie:
typenamebasic_istream<charT,Traits>::sentryinit(flux);
if(init)
{
//Lectureduprnometdunom:
flux >> p.Prenom;
flux >> p.Nom;
//Lecturedelge:
flux >> p.Age;
//Lecturedelatailleenmtres:
doubleTaille;
flux >> Taille;
//Conversionencentimtres;
p.Taille=(int)(Taille*100+0.5);
}
returnflux;
}
intmain(void)
{
//Construitunenouvellepersonne:
Personnep;
//Demandelasaisiedunepersonne:
cout << "PrnomNomge(ans)Taille(m):";
cin >> p;
//Affichelesvaleurslues:
cout << endl;
cout << "Valeurssaisies:" << endl;
cout << p.Prenom << "" << p.Nom << "a"
<<
p.Age << "ansetmesure"
<<
p.Taille << "cm." << endl;
return0;
}
Note:Laclassesentryest galement utiliseparlesmthodesdelecturededonnesnon
formates.Pourcesmthodes,lescaractresblancssontimportantsetdanscecaslesecond
true.
paramtrefourniauconstructeurdelaclassesentryest
Commepourlaclassesentrydelaclassebasic_ostream, lutilisationdelobjet dinitialisation
danslestestsest renduepossibleparlaprsencedeloprateurdetranstypageversletype
bool.Lavaleurretourneesttrue silinitialisationsestbienfaiteet false danslecascontraire.
308
Chapitre15.Lesfluxdentre/sortie
Remarquezgalement queleconstructeurdelaclassesentryest susceptibledelancerdes
exceptionsselonlaconfigurationdumasquedexceptionsdanslaclassedeflux.
Lesoprationsdelecturededonnesnonformatessontunpeuplusnombreusespourlesfluxdentre
quelesoprationsdcriturenonformatespourlesfluxdesortie.Eneffet,laclassebasic_istream
donnenonseulementlapossibilitdelireuncaractresimpleouunesriedecaractres,maisausside
lirelesdonnesprovenantdutampondelectureetdelesinterprterentantquelignes.Uneligne
estenralitunesriedecaractrestermineparuncaractrespcialquelonnommelemarqueur
defindeligne.Engnral,cemarqueurestlecaractre\n,maisilestpossibledespcifierunautre
caractre.
Lalectureduncaractreuniquedanslefluxdentresefaitlaidedelamthodeget.Ilexistedeux
surchargesdecettemthode,lapremireneprenantaucunparamtreetrenvoyantlecaractrelu,et
ladeuximeprenantenparamtreunerfrencesurlavariabledevantrecevoirlecaractreluetne
renvoyantrien.Cesdeuxmthodesextraientlescaractresquelleslisentdutampondentrequele
fluxutilise.Silonveutsimplementlirelavaleurducaractresuivantsanslenextraire,ilfautappeler
lamthode peek.Deplus,toutcaractreextraitpeuttrerinsrdanslefluxdentre(pourvuquele
tamponsousjacentacceptecetteopration)laidedelunedesdeuxmthodes unget ou putback.
Cettederniremthodeprendenparamtrelecaractrequidoittrerinsrdanslefluxdentre.
Notezquelarinsertionnepeuttreralisequesilecaractrefournienparamtreestprcisment
lederniercaractreextrait.
Silondsireraliserlalecturedunesriedecaractresaulieudelesextraireunun,ilfaututiliser
lamthode read.Cettemthodeestlamthodedebasepourleslecturesnonformatespuisquellelit
lesdonnesbrutesdefonderie,sanslesinterprter.Elleprendenparamtreunpointeursuruntableau
decaractresdanslequellesdonnesserontcritesetlenombredecaractreslire.Cettemthode
nevrifiepaslatailledutableauspcifi,aussiceluicidoitiltrecapabledaccueillirlenombrede
caractresdemand.Ilexisteunevariantedelamthoderead,lamthode readsome,quipermetde
lirelesdonnesprsentesdansletampongrparlefluxsansaccderaumdiaquecedernierprend
encharge. Cettemthodeprendgalement enparamtreunpointeursurlazonemmoiredevant
recevoirlesdonnesetlenombredecaractresdsir,mais,contrairementlamthode read,elle
peutnepaslireexactementcenombre.Eneffet,lamthode readsome sarrtedsqueletampon
utilisparlefluxestvide,cequipermetdviterlesaccssurlepriphriqueauquelcetampondonne
accs.Lamthode readsome renvoielenombredecaractreseffectivementlus.
Lesmthodesdelecturedeslignessontdiviserendeuxcatgories.Lapremirecatgorie,constitue
deplusieurssurchargesdelamthode get, permetdeffectuerunelecturedesdonnesdutampon
jusqucequeletableaufourni enparamtresoit rempli ouquunefindelignesoit atteinte. La
deuximecatgoriedemthodesestconstituedessurchargesdelamthodegetline.Cesmthodes
sedistinguentdesmthodes get parlefaitquellesnchouentpaslorsquelalignelue(dlimiteurde
lignecompris)remplitcompltementletableaufournienparamtredunepart,etparlefaitquele
dlimiteurdeligneestextraitdutampondentreutilisparlefluxdautrepart.Autrementdit,siune
lignecomplte(cestdireavecsondlimiteur)aunetailleexactementgalelatailledutableau
fournienparamtre,lesmthodes get chouerontalorsquelesmthodes getline russiront,car
ellesneconsidrentpasledlimiteurcommeuneinformationimportante.Cecirevientdirequeles
mthodes getline interprtentcompltementlecaractredlimiteur,alorsquelesmthodes get le
traitentsimplementcommelecaractreauquellalecturedoitsarrter.
Danstouslescas,uncaractrenulterminalestinsrenlieuetplacedudlimiteurdansletableau
fournienparamtreetdevantrecevoirlesdonnes.Commeledeuximeparamtredecesmthodes
indiqueladimensiondecetableau,lenombredecaractresluestaupluscettedimensionmoinsun.
Lenombredecaractresextraitsdutampondentreestquantluircuprablegrcelamthode
gcount.Remarquezquelecaractredefindeligneestcomptdanslenombredecaractresextraits
309
Chapitre15.Lesfluxdentre/sortie
pourlesmthodes getline,alorsquilnelestpaspourlesmthodes get puisquecesderniresne
lextraientpasdutampon.
Enfin,ilestpossiblededemanderlalectureduncertainnombredecaractresetdelespassersans
enrcuprerlavaleur. Cetteoprationestralisablelaidedelamthode ignore, quineprend
doncpasdepointeurssurlazonemmoireolescaractreslusdoiventtrestockspuisquilssont
ignors.Cettemthodelitautantdecaractresquespcifi,saufsilecaractredlimiteurindiquen
deuximeparamtreestrencontr.Danscecas,cecaractreestextraitdutampondentre,cequifait
quelamthode ignore secomporteexactementcommelesmthodes getline.
Exemple158.Lecturesdelignessurlefluxdentrestandard
#include <iostream>
#include <sstream>
usingnamespacestd;
intmain(void)
{
//Tableaudevantrecevoiruneligne:
charpetit_tableau[10];
//Litunelignede9caractres:
cout << "Saisissezuneligne:" << endl;
cin.getline(petit_tableau,10);
if(cin.fail())
cout << "Lignetroplongue!" << endl;
cout << "Lu:***" << petit_tableau << "***" << endl;
//Litunelignedetaillearbitraireviauntampon:
cout << "Saisissezuneautreligne:" << endl;
stringbufs;
cin.get(s);
//Affichelalignelue:
cout << "Lu:***" << s.str() << "***";
//Extraitlecaractredesautdeligne
//etajouteleaufluxdesortiestandard:
cout << (char)cin.get();
return0;
}
Note:Remarquezquelecaractredesaut delignetant lu, il est ncessairedesaisirdeux
retoursdechariot successifspourquelamthode getline renvoiesonrsultat. Commepour
touteslesmthodesdelecturesformates,cecaractreinterromptlalecturedanslefluxdentre
standardduprogrammeet setrouvedoncencoredansletampondentrelorsdelalecture
suivante.Celaexpliquequedanslecasdelecturessuccessives,il fautextrairececaractredu
fluxdentremanuellement,parexemplelaidedelamthode get.Cestcequecetexemple
ralisesursadernirelignepourlenvoyersurlefluxdesortiestandard.
Deplus,onnepeutpasprvoir,apriori,quelleseralatailledeslignessaisiesparlutilisateur.
Onneprocderadoncpascommeindiqudanscetexemplepoureffectuerlalecturedelignes
enpratique. Il est eneffet plusfaciledutiliser lafonction getline, quelonadcrit dansla
Section14.1.8danslecadredutypebasic_string.Eneffet,cettefonctionpermetdelireuneligne
compltesansavoirsesoucierdesalongueurmaximaleet destockerlersultat dansune
basic_string.
310
Chapitre15.Lesfluxdentre/sortie
Laclassebasic_istreamdisposegalementdemthodespermettantdemanipulerletamponquelle
utilisepourliredenouvellesdonnes.Lamthode sync permetdesynchroniserletampondentre
aveclemdiaauquelildonneaccs, puisquelleappellelamthode pubsync decetampon. Pour
lesfluxdentre,celanapasrellementdimportanceparcequelonnepeutpascrirededans.La
mthode tellg permetdedterminerlapositiondupointeurdelecturecourant,etlesdeuxsurcharges
delamthode seekg permettentderepositionnercepointeur.Nousverronsunexempledutilisation
decesmthodesdansladescriptiondesclassesdefluxpourlesfichiers.
Enfin,lesfluxdentredisposentgalementdequelquesmanipulateurspermettantdelesconfigurer
simplementlaidedeloprateur operator>>.Cesmanipulateurssontprsentsdansletableau
cidessous:
Tableau157.Manipulateursdesfluxdentre
Manipulateur
Fonction
boolalpha
Activelinterprtationdesboolenssousformedetextuelle.
noboolalpha
Dsactivelinterprtationdesboolenssousformetextuelle.
hex
Utiliselabase16pourlinterprtationdesnombresentiers.
oct
Utiliselabase8pourlinterprtationdesnombresentiers.
dec
Utiliselabase10pourlinterprtationdesnombresentiers.
skipws
Ignorelesespaceslorsdesentresformates.
noskipws
Conservelesespaceslorsdesentresformates.
ws
Supprimetouslesespacesprsentsdanslefluxdentrejusquau
premiercaractrenonblanc.
Cesmanipulateurssutilisentdirectementlaidedeloprateur operator>>,exactementcomme
lesmanipulateursdelaclassebasic_ostreamsutilisentavecloprateurdinsertionnormal.
15.4.3.Laclassebasic_iostream
Labibliothquestandarddfinitdanslentte iostream laclasse template basic_iostreamafin
depermettrelafoislesoprationsdcritureetlesoprationsdelecturesurlesflux.Enfait,cette
classenestriendautrequuneclassedrivedesdeuxclassesbasic_ostreametbasic_istreamqui
fournissentrespectivement,commeonlavu,touteslesfonctionnalitsdelectureetdcrituresurun
tampon.
Laclassebasic_iostreamnecomportepasdautresmthodesquunconstructeuretundestructeur,
quiserventuniquementinitialiseretdtruirelesclassesdebasebasic_ostreametbasic_istream.
Lutilisationdecetteclassenedoitdoncpasposerdeproblmeparticulieretjevousinvitevous
rfrerauxdescriptionsdesclassesdebasesibesoinest.
Note:Toutcommesesclassesdebase,laclassebasic_iostreamserararementutilisedirecte
ment. Eneffet, elledisposedeclassesdrivesspcialisesdanslesoprationsdcritureet
delecturesurfichiersoudansdeschanesdecaractres,classesquelonprsenteradansles
sectionssuivantes.Cesontcesclassesquelonutiliseraenpratiquelorsquelondsireracrer
unnouveaufluxpourlireetcriredansunfichieroudansunebasic_string.
Vousaurezpeuttreremarququelesclassesbasic_ostreamet
basic_istreamutilisent un
hritagevirtuel pourrcuprerlesfonctionnalitsdelaclassedebasebasic_ios.Laraisonen
est quelaclassebasic_iostreamraliseunhritagemultiplesursesdeuxclassesdebaseet
quelesdonnesdelaclassebasic_iosnedoiventtreprsentequenunseulexemplairedans
lesfluxdentre/sortie.Celaimpliquequelesconstructeursdesclassesdrivesdelaclasse
311
Chapitre15.Lesfluxdentre/sortie
basic_iostreamprenantdesparamtresdoiventappelerexplicitementlesconstructeursdetoutes
leurclassesdebase.VoyezlaSection8.6pourplusdedtailssurlesnotionsdhritagemultiple
etdeclassesvirtuelles.
15.5.Lesfluxdentre/sortiesurchanesde
caractres
Afindedonnerlapossibilitauxprogrammeursdeffectuerlesoprationsdeformatagedesdonnes
enmmoireaussisimplementquaveclesclassesdegestiondesfluxdentre/sortiestandards,
la
bibliothquedentre/sortiedfinittroisclassesdefluxcapablesdetravaillerdansdeschanesde
caractresdetypebasic_string. Cesclassessontlesclassesbasic_ostringstream, pourlescritures
dansleschanesdecaractres, basic_istringstream, pourleslecturesdedonnesstockesdansles
chanesdecaractres,etbasic_stringstream,pourlesoprationslafoisdcritureetdelecture.
Ces classes drivent respectivement des classes de flux basic_istream, basic_ostreamet
basic_iostreametreprennentdoncleurcomptetouteslesfonctionsdeformatageetdcriturede
cesclasses. Lescrituresetleslecturesdedonnesenmmoiresefontdonc,
grcecesclasses,
aussi facilement quavecles fluxdentre/ sortiestandards, et cedemanirecompltement
transparente.
Enfait, lesclassesdefluxorienteschanesdecaractresfonctionnent
exactement commeleurs
classesdebase,cartouteslesfonctionnalitsdegestiondeschanesdecaractressontencapsulesau
niveaudesclassesdegestiondestamponsquionttprsentesaudbutdecechapitre.Cependant,
ellesdisposentdemthodesspcifiquesquipermettentdemanipulerleschanesdecaractressur
lesquellesellestravaillent.Parexemple,laclassebasic_ostringstreamestdclarecommesuitdans
lentte sstream :
template <classcharT,
classtraits=char_traits
<charT>,
classAllocator=allocator
<charT>>
classbasic_ostringstream:publicbasic_ostream
<charT,traits>
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
//Lesconstructeursetdestructeurs:
explicitbasic_ostringstream(ios_base::openmodemode=ios_base::out);
explicitbasic_ostringstream(
constbasic_string<charT,traits,Allocator> &chaine,
ios_base::openmodemode=ios_base::out);
virtual~basic_ostringstream();
//Lesmthodesdegestiondelachanedecaractres:
basic_stringbuf<charT,traits,Allocator
> *rdbuf()const;
basic_string<charT,traits,Allocator
> str()const;
void
str(constbasic_string<charT,traits,Allocator
> &chaine);
};
312
Chapitre15.Lesfluxdentre/sortie
Lesclassesbasic_istringstreametbasic_stringstreamsontdclaresdemanireidentique,ceciprs
quelesclassesdebaseetlesvaleurspardfautpourlesmodesdouverturedutamponsurlachane
decaractresnesontpaslesmmes.
Commevouspouvezleconstater,ilestpossibledeconstruireunfluxdentre/sortiesurunechane
decaractresdediffrentesmanires.Lapremiremthodeestdeconstruireunobjetflux,puisde
prciser,pourlesfluxdentre,lachanedecaractresdanslaquellelesdonnesliresetrouvent
laidedelamthode str.Ladeuximemthodeesttoutsimplementdefournirtouslesparamtres
enuneseulefoisauconstructeur.Engnral,lesvaleurspardfautspcifiesdanslesconstructeurs
correspondentcequelonveutfaireaveclesflux, cequifaitquelaconstructiondecesfluxest
extrmementsimple.
Unefoisconstruit, ilestpossiblederalisertouteslesoprationsquelondsiresurleflux.
Dans
lecasdesfluxdentre, ilestncessairequelefluxaittinitialisavecunechanedecaractres
contenantlesdonneslire,etlonnecherchegnralementpasrcuprercettechaneaprsusage
duflux.Pourlesfluxdesortie,cetteinitialisationestinutile.Enrevanche,lersultatdesoprations
deformatageseragnralementrcuprlaidedelamthode str unefoiscellesciralises.
Exemple159.Utilisationdefluxdentre/sortiesurchanesdecaractres
#include <iostream>
#include <sstream>
#include <string>
usingnamespacestd;
intmain(void)
{
//Lituneligneenentre:
cout << "EntierRelChane:";
stringinput;
getline(cin,input);
//Interprtelalignelue:
istringstreamis(input);
inti;
doubled;
strings;
is >> i >> d;
is >> ws;
getline(is,s);
//Formatelarponse:
ostringstreamos;
os << "Larponseest:"
<< endl;
os << s << "" << 2*i << "" << 2*d << endl;
//Affichelachanedelarponse:
cout << os.str();
return0;
}
Commelexempleprcdentvouslemontre,lutilisationdesfluxdentre/sortiedelabibliothque
standardsurleschanesdecaractresestrellementaise. Commecesoprationsnepeuventtre
ralisesquenmmoire, cest direendehorsducontextedusystmedexploitationutilis,
les
classesdefluxdelabibliothquerestentutilesmmesilesoprationsdentre/sortiedusystmese
fontdetellemanirequelesobjets cin et cout nesontpratiquementpasutilisables.
313
Chapitre15.Lesfluxdentre/sortie
15.6.Lesfluxdentre/sortiesurfichiers
Lesclassesdentre/ sortiesurlesfichierssont implmentesdemaniresimilaireauxclasses
dentre/sortiesurleschanesdecaractres,ceciprsqueleursmthodesspcifiquespermettent
demanipulerunfichieraulieudunechanedecaractres.Ainsi,laclassebasic_ofstreamdrivede
basic_ostream, laclassebasic_ifstreamdelaclassebasic_istream, etlaclassebasic_fstreamdela
classebasic_iostream. Toutescesclassessontdclaresdanslentte fstream. Voustrouverez
titredexempleladclarationdelaclassebasic_ofstreamtelquilapparatdanscetentte:
template <classcharT,
classtraits=char_traits
<charT>>
classbasic_ofstream:publicbasic_ostream <charT,traits>
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedeftypenametraits::int_typeint_type;
typedeftypenametraits::pos_typepos_type;
typedeftypenametraits::off_typeoff_type;
//Lesconstructeursetdestructeurs:
basic_ofstream();
explicitbasic_ofstream(constchar*nom,
ios_base::openmodemode=ios_base::out|ios_base::trunc);
//Lesmthodesdegestiondufichier:
basic_filebuf<charT,traits> *rdbuf()const;
boolis_open();
voidopen(constchar*nom,ios_base::openmodemode=out|trunc);
voidclose();
};
Commepourlesfluxdentre/sortiesurleschanesdecaractres,ilestpossibledinitialiserleflux
dssaconstructionouaposteriori. Lesmthodesimportantessontbienentendulamthode open,
quipermetdouvrirunfichier,lamthode is_open,quipermetdesavoirsilefluxcontientdjun
fichierouvertounon,etlamthode close,quipermetdefermerlefichierouvert.
Exemple1510.Utilisationdefluxdentre/sortiesurunfichier
#include <iostream>
#include <fstream>
#include <string>
usingnamespacestd;
intmain(void)
{
//Litlesdonnes:
inti;
doubled,e;
cout << "EntierRelRel:";
cin >> i >> d >> e;
//Enregistrecesdonnesdansunfichier:
ofstreamf("fichier.txt");
if(f.is_open())
314
Chapitre15.Lesfluxdentre/sortie
{
f << "Lesdonnesluessont:"
<<
i << "" << d << "" << e << endl;
f.close();
}
return0;
}
Note:Ilestimportantdebiennoterqueledestructeurdesfluxnefermepaslesfichiers.Eneffet,
cesontlestamponsutilissdemaniresousjacenteparlesfluxquiralisentlesoprationssur
lesfichiers.Ilestmmetoutfaitpossibledaccderunmmefichieravecplusieursclassesde
flux,bienquecelanesoitpasfranchementrecommand.Vousdevrezdoncprendreencharge
vousmmelesoprationsdouvertureetdefermeturedesfichiers.
Bienentendu,lesclassesdefluxpermettantdaccderdesfichiershritentdesmthodesdeposition
nementdeleursclassesdebase.Ainsi,lesclassesdelecturedansunfichierdisposentdesmthodes
tellg et seekg,etlesclassesdcrituredisposentdesmthodes tellp et seekp.Cesoprations
permettentrespectivementdelireetdefixerunenouvellevaleurdupointeurdepositiondufichier
courant.
Exemple1511.Repositionnementdupointeurdefichierdansunfluxdentre/sortie
#include <iostream>
#include <fstream>
#include <string>
usingnamespacestd;
intmain(void)
{
//Ouvrelefichierdedonnes:
fstreamf("fichier.txt",
ios_base::in|ios_base::out|ios_base::trunc);
if(f.is_open())
{
//critlesdonnes:
f << 2 << "" << 45.32 << "" << 6.37 << endl;
//Replacelepointeurdefichieraudbut:
f.seekg(0);
//Litlesdonnes:
inti;
doubled,e;
f >> i >> d >> e;
cout << "Lesdonnesluessont:" <<
i << "" << d << "" << e << endl;
//Fermelefichier:
f.close();
}
return0;
}
Note:Lesclassesdentre/ sortiesurfichiernutilisent quunseul tamponpouraccderaux
fichiers. Parconsquent, il nexistequuneseulepositiondanslefichier, qui sert lafoisla
lectureetlcriture.
315
Chapitre15.Lesfluxdentre/sortie
316
Chapitre16.Leslocales
Il existedenombreuxalphabetset denombreusesmaniresdcrirelesnombres, lesdateset les
montantsdepartlemonde.Chaquepays,chaqueculturedisposeeneffetdesespropresconventions
etdesespropresrgles,etcedansdenombreuxdomaines.Parexemple,lesAnglosaxonsontpour
coutumedutiliserlepoint(caractre .)poursparerlesunitsdelavirgulelorsquilscriventdes
nombresvirguleetdutiliserunevirgule(caractre ,)entrechaquegroupedetroischiffrespour
sparerlesmilliersdesmillions,lesmillionsdesmilliards,etc.EnFrance,cestlavirguleestutilise
poursparerlesunitsdelapartiefractionnairedesnombresvirgule,etlesparateurdesmilliers
estsimplementunespace.Demme,ilsontlhabitudedcrirelesdatesenmettantlemoisavantles
jours,alorsquelesFranaisfontlinverse.
Ilvadesoiquecegenredediffrencesrendtechniquementtrsdifficilelinternationalisationdes
programmes.Unesolutionesttoutsimplementdedirequelesprogrammestravaillentdansunelangue
neutre,cequienpratiquerevientsouventdirelanglaispuisquecestlalanguehistoriquement
laplusutiliseeninformatique.Hlas,sicelaconvenaitparfaitementauxprogrammeurs,ceneserait
certainement paslecasdesutilisateurs!Il faut donc, unmoment donnouunautre, queles
programmesprennentencomptelesconventionslocalesdechaquepaysoudechaquepeuple.
Cesconventionssontextrmementnombreusesetportentsurdesdomainesaussidiversetvarisque
lamaniredcrirelesnombres,lesdatesoudecoderlescaractresetdeclasserlesmotsdansun
dictionnaire.Eninformatique,ilestcourantdappelerlensembledesconventionsdunpayslalocale
decepays.Lesprogrammesquiprennentencomptelalocalesontdoncditslocalissetsontcapables
desadapterauxprfrencesnationalesdelutilisateur.
Note:Lefaitdtrelocalisnesignifiepaspourautantpourunprogrammequetoussesmes
sagessont traduitsdanslalanguedelutilisateur. Lalocalisationneprendencomptequeles
aspectsconcernantlcrituredesnombresetlesalphabetsutiliss.Afindebienfairecettedis
tinction,onditquelesprogrammescapablesdecommuniqueraveclutilisateurdanssalangue
sont internationaliss.Laconversiondunprogrammedunpaysunautrencessitedoncla
foislalocalisationdeceprogrammeetsoninternationalisation.
Silatraductiondetouslesmessagesdunprogrammenepeutpastreraliseautomatiquement,il
esttoutefoispossibledeprendreencompteleslocalesrelativementfacilement. Eneffet, lesfonc
tionnalitsdesbibliothquesCet C++, enparticulierlesfonctionnalitsdentre/ sortie, peuvent
gnralement treparamtresparlalocaledelutilisateur.
Lagestiondeslocalesest donccom
pltementpriseenchargeparcesbibliothquesetunmmeprogrammepeutdonctreutilissans
modificationdansdiverspays.
Note:Enrevanche, latraductiondesmessagesnepeut bienvidemment pastrepriseen
chargeparlabibliothquestandard,saufventuellementpourlesmessagesderreurdusystme.
Laralisationdunprogrammeinternationalncessitedoncdeprendredesmesuresparticulires
pourfaciliterlatraductiondecesmessages. Engnral, cesmesuresconsistent isolerles
messagesdansdesmodulesspcifiqueset nepaslesutiliserdirectement danslecodedu
programme.Ainsi,il suffitsimplementdetraduirelesmessagesdecesmodulespourajouterle
support dunenouvellelangueunprogrammeexistant. Lecodesourcenaainsi pastre
touch,cequilimitelesrisquesderreurs.
LagestiondeslocalesenC++sefaitparlintermdiaireduneclassegnrale,laclasselocale,qui
permetdestockertouslesparamtreslocauxdespays.Cetteclasseestbienentenduutiliseparles
fluxdentre/ sortiedelabibliothquestandard, cequi fait quevousnaurezgnralement qu
317
Chapitre16.Leslocales
initialisercetteclasseaudbut devosprogrammespourleurfaireprendreencompteleslocales.
Cependant, ilsepeutquevousayezmanipulervousmmedeslocalesoudfinirdenouvelles
conventionsnationales,surtoutsivouscrivezdessurchargesdesoprateursdeformatagedesflux
operator<< et operator>>.Cechapitreprsentedonclesnotionsgnralesdeslocales,lesdif
frentesclassesmisesenoeuvreauseindunemmelocalepourprendreenchargetouslesaspectsde
lalocalisation,etlamanirededfinirouderedfinirundecesaspectsafindecomplterunelocale
existante.
16.1.Notionsdebaseetprincipedefonctionnement
desfacettes
Commeillatditplushaut,leslocalescomprennentdiffrentsaspectsquitraitentchacundune
desconventionsnationalesdelalocale.Parexemple,lamaniredcrirelesnombresconstitueunde
cesaspects,toutcommelamaniredeclasserlescaractresoulamaniredcrirelesheuresetles
dates.
ChacundecesaspectsconstituecequelabibliothquestandardC++appelleunefacette.Lesfacettes
sontgrespardesclassesC++,dontlesmthodespermettentdobtenirlesinformationsspcifiques
auxdonnesquellesmanipulent.Certainesfacettesfournissentgalementdesfonctionspermettant
deformateretdinterprtercesdonnesentenantcomptedesconventionsdeleurlocale.
Chaque
facetteestidentifiedemanireuniquedansleprogramme,etchaquelocalecontientunecollection
defacettesdcrivanttoussesaspects.
LabibliothquestandardC++fournitbienentenduuncertainnombredefacettesprdfinies. Ces
facettessontregroupesencatgoriesquipermettentdelesclasserenfonctiondutypedesoprations
quellespermettentderaliser.Labibliothquestandarddfinitsixcatgoriesdefacettes,auxquelles
correspondentlesvaleursdesixconstantesdelaclasselocale:
lacatgorie ctype,quiregroupetouteslesfacettespermettantdeclassifierlescaractresetdeles
convertirdunjeudecaractreenunautre;
lacatgorie message,quicontientuneuniquefacettepermettantdefaciliterlinternationalisation
desprogrammesentraduisantlesmessagesdestinsauxutilisateurs.
enchargeleformatagedes
lcrituredes
Bienentendu,ilestpossiblededfinirdenouvellesfacettesetdelesincluredansunelocaleexistante.
Cesfacettesneserontvidemmentpasutilisesparlesfonctionsdelabibliothquestandard,maisle
programmepeutlesrcupreretlesutiliserdelammemanirequelesfacettesstandards.
Lesmcanismesdedfinition,didentificationetdercuprationdesfacettes,sonttousprisencharge
auniveaudelaclasselocale.Ladclarationdecetteclasseestralisedelamaniresuivantedans
lentte locale :
318
Chapitre16.Leslocales
classlocale
{
public:
//Lestypesdedonnes:
//Lescatgoriesdefacettes:
typedefintcategory;
staticconstcategory
//Lesvaleursdecesconstantes
{
//sontspcifiqueschaqueimplmentation
none
=VAL0,
ctype
=VAL1,collate =VAL2,
numeric =VAL3,monetary=VAL4,
time
=VAL5,messages=VAL6,
all=collate|ctype|monetary|numeric|time |messages;
};
//Laclassedebasedesfacettes:
classfacet
{
protected:
explicitfacet(size_trefs=0);
virtual~facet();
private:
//Cesmthodessontdclaresmaisnondfinies:
facet(constfacet&);
voidoperator=(constfacet&);
};
//Laclassedidentificationdesfacettes:
classid
{
public:
id();
private:
//Cesmthodessontdclaresmaisnondfinies:
voidid(constid&);
voidoperator=(constid&);
};
//Lesconstructeurs:
locale()throw()
explicitlocale(constchar*nom);
locale(constlocale&)throw();
locale(constlocale&init,constchar*nom,categoryc);
locale(constlocale&init1,constlocale&init2,categoryc);
template <classFacet>
locale(constlocale&init,Facet*f);
template <classFacet>
locale(constlocale&init1,constlocale&init2);
//Ledestructeur:
~locale()throw();
//Oprateurdaffectation:
constlocale&operator=(constlocale&source)throw();
319
Chapitre16.Leslocales
//Lesmthodesdemanipulationdeslocales:
basic_string<char> name()const;
booloperator==(constlocale&)const;
booloperator!=(constlocale&)const;
template <classcharT,classTraits,classAllocator
>
booloperator()(
constbasic_string<charT,Traits,Allocator> &s1,
constbasic_string<charT,Traits,Allocator> &s2)const;
//Lesmthodesdeslectiondeslocales:
static
locale global(constlocale&);
staticconstlocale&classic();
};
Commevouspouvezleconstater,outrelesconstructeurs,destructeuretmthodesgnrales,laclasse
localecontientladclarationdedeuxsousclassesutilisespourladfinitiondesfacettes:laclasse
facetetlaclasseid.
Laclassefacetestlaclassedebasedetouteslesfacettes.Sonrleestessentiellementdviterque
lonpuissedupliquerunefacetteouencopierune,cequiestralisendclarantenzoneprivele
constructeurdecopieetloprateurdaffectation.Commecesmthodesnedoiventpastreutilises,
ellesnesontpasdfiniesnonplus,seuleladclarationestfournieparlabibliothquestandard.Notez
quecelanestpasdrangeantpourlutilisationdelaclassefacet,puisquecommecesmthodesne
sontpasvirtuellesetquellesneserontjamaisutilisesdanslesprogrammes, lditeurdeliensne
chercherapasleslocaliserdanslesfichiersobjetsduprogramme.Ainsi,lesinstancesdefacettes
nepeuventtrenicopies,nidupliques.Enfait,lesfacettessontdestinestreutilisesausein
deslocales,quiprennentenchargelagestiondeleurduredevie.Toutefois,silondsiregrersoi
mmeladuredeviedunefacette,ilestpossibledelesignalerlorsdelaconstructiondelafacette.
Leconstructeurdebasedelaclassefacetprendeneffetunparamtreuniquequiindiquesiladurede
viedelafacettedoittrepriseenchargeparlalocaledanslaquelleellesetrouveousielledevratre
explicitementdtruiteparleprogrammeur(auquelcasceparamtredoittrefix 1).Engnral,la
valeurpardfaut 0 convientdanslamajoritdescasetilnestpasncessairedefournirdeparamtre
auconstructeurdesfacettes.
Laclasseidquantelleestutilisepourdfinirdesidentifiantsuniquespourchaqueclassedefacette.
Cesidentifiantspermettentlabibliothquestandarddedistinguerlesfacetteslesunesdesautres,
laideduneclefuniquedont leformat nest passpcifi, maisqui est dtermineparlaclasse
idautomatiquementlorsdelapremirecrationdechaquefacette.Cetidentifiantestenparticulier
utilispourretrouverlesfacettesdanslacollectiondesfacettesgresparlaclasselocale.
Pourquecemcanismedenregistrementfonctionne,ilfautquechaqueclassedefacettedfinisseune
donnemembrestatique id enzonepublique,dontletypeestlasousclasseiddelaclasselocale.
Cettedonnemembretantstatique, elleappartientlaclasseetnonchaqueinstance, etpermet
doncbiendidentifierchaqueclassedefacette. Lorsduchargement duprogramme, lesvariables
statiquessontinitialises0,cequifaitquelesfacettesdisposenttoutesdunidentifiantnul.Ceci
permetauxmthodesdelabibliothquestandarddedterminersiunidentifiantadjtattribula
classedunefacetteounonlorsquelleestutilisepourlapremirefois.Sicestlecas,cetidentifiant
estutilistelquelpourrfrencercetteclasse,sinon,ilestgnrautomatiquementetstockdansla
donnemembre id delaclasse.
Ainsi, pour dfinir unefacette, il suffit simplement dcrireuneclassedrivant delaclasselo
cale::facetetcontenantunedonnemembrestatiqueetpubliqueid detypelocale::id.Dslors,cette
facetteseverraattribuerautomatiquementunidentifiantunique,quipermettradutiliserlesfonctions
derecherchedefacettesdansleslocales.Cesfonctionsutilisentbienentenduladonnemembre id
320
Chapitre16.Leslocales
dutypedelafacetterechercheretsenservententantquindexdanslacollectiondesfacettesdela
localeutiliser.LamanirederalisercesoprationsnestpasdcriteparlanormeduC++,maisle
principeestl.
Lesfonctionsderecherchedesfacettessontgalementdclaresdanslentte locale.Cesontdes
fonctions template paramtresparletypedesfacettes,quiprennentenparamtrelalocaledans
laquellelafacettedoittrerecherche:
template <classFacet>
constFacet&use_facet(constlocale&);
template <classFacet>
bool
has_facet(constlocale&);
Lesfacettesfourniesparlabibliothquestandardsontgnralementdisponiblesetpeuventtreuti
lisesavecleslocales.Lesmthodesspcifiqueschacunedecesfacettespeuventdonctreappe
use_facet. Enrevanche, lesfacettes
lessurlarfrencedelafacetteretourneparlafonction
dfiniesparlutilisateurpeuventnepastreprsentesdanslalocalefournieenparamtrelafonc
tion use_facet.Danscecas,cettefonctionlanceuneexceptiondetypebad_cast.Commeilpeut
treutileencertainescirconstancesdedterminerdynamiquementsiunelocalecontientounonune
facette, labibliothquestandardmet dispositionlafonctionglobale has_facet. Cettefonction
sutilisedelammemanirequelafonction use_facet, maisaulieuderenvoyerlafacettede
mande, elleretourneunboolenindiquantsilalocalefournieenparamtrecontientounoncette
facette.
Lesprogrammespeuventcrerplusieurslocalesafindeprendreencompteplusieursjeuxdepara
mtresinternationauxsilsledsirent,maisilsdoiventdanscecasmanipulerceslocaleseuxmmes
danstouteslesoprationssusceptiblesdutiliserlanotiondelocale.Parexemple,ilsdoiventspcifier
imbue desflux
lalocaleutiliseravantchaqueoprationdentre/sortieenappelantlamthode
utiliss.Commecelanestpastrspratique,labibliothquestandarddfinitunelocaleglobale,qui
estlalocaleutilisepardfautlorsquunprogrammenedsirepasspcifierexplicitementlalocale
utiliser.Cettelocalepeuttrercupretoutmomentencrantunsimpleobjetdetypelocale,en
utilisantleconstructeurpardfautdelaclasselocale.Ceconstructeurinitialiseeneffetlalocaleen
coursdeconstructionavectouslesparamtresdelalocaleglobale.Ainsi,pourrcuprerlafacette
num_put<char> delalocaleglobale,onferalappelsuivant:
use_facet<num_put<char>> (locale());
321
Chapitre16.Leslocales
"C", "",outouteautrevaleurdontlasignificationnestpasnormalise.Lenomdelocalevide(
"")
permetdeconstruireunelocaledontlesparamtressontinitialissenfonctiondelenvironnement
dexcutionduprogramme. Cest donclavaleurquelonutiliseraengnral, carcelapermet de
paramtrerlecomportementdesprogrammesfacilement,sansavoirlesmodifieretlesrecompiler.
Note:Lamanirededfinirlalocaledanslenvironnement dexcutiondesprogrammesest
spcifiquechaquesystmedexploitationet nest normalisni parlanormeC++, ni parla
normeC.LanormePOSIXprcisecependantquecelapeuttreralisparlintermdiairede
variablesdenvironnement.Parexemple,silavariabledenvironnementLANGnestpasdfinie,la
localeutiliseseralalocaledelabibliothqueC.Enrevanche,sicettevariabledenvironnement
contientlavaleur "fr_FR",lalocaleutiliseseracelledesfrancophonesdeFrance.Lesformats
desnombres,desdates,etc.utilissserontdoncceuxquisontenvigueurenFrance.
Lesautresconstructeursdelaclasselocalepermettentdecrerdenouvelleslocalesenrecopiantles
facettesdunelocaleexistante,ventuellementenajoutantdenouvellesfacettesnonstandardsouen
redfinissantcertainesfacettesdelalocalemodle. Bienentendu, leconstructeurdecopierecopie
touteslesfacettesdelalocalesourcedanslalocaleencoursdeconstruction.
Lesdeuxconstruc
teurssuivantspermettentderecopiertouteslesfacettesdunelocale,sauflesfacettesidentifiespar
lacatgoriespcifieentroisimeparamtre. Pourcettecatgorie, lesfacettesutilisessontcelles
delalocalespcifieendeuximeparamtre.
Il est possibleici didentifiercettedeuximelocale
soitparsonnom,soitdirectementparlintermdiairedunerfrence.Enfin,lesdeuxconstructeurs
template permettentdecrerunelocaledonttouteslesfacettessontinitialisespartirdunelo
calefournieenparamtre, sauflafacettedontletypeestutilisentantqueparamtre template.
Pourcettefacette,lavaleurutiliserpeuttrespcifiedirectementendeuximeparamtreouex
traiteduneautrelocale,elleaussispcifieendeuximeparamtre.Nousverronsplusendtaildans
laSection16.3lamaniredeprocderpourinsrerunenouvellefacetteouremplacerunefacette
existante.
Enfin,laclasselocaledisposededeuxmthodesstatiquespermettantdemanipulerleslocalesdupro
gramme.Lamthode classic quelonautilisedanslundesexemplesprcdentspermetdobtenir
lalocalereprsentantlesoptionsdelabibliothqueCstandard.Cettelocaleestlalocaleutilisepar
dfautparlesprogrammesquinedfinissentpasleslocalesutilises.Lamthode global quant
ellepermetdespcifierlalocaleglobaleduprogramme.Cettemthodeprendenparamtreunobjet
detypelocalepartirduquellalocaleglobaleestinitialise.Ilestdonccourantdefaireunappel
cettemthodedsledbutdesprogrammesC++.
Exemple161.ProgrammeC++prenantencomptelalocaledelenvironnement
#include <ctime>
#include <iostream>
#include <locale>
usingnamespacestd;
intmain(void)
{
//Utiliselalocaledfiniedanslenvironnement
//dexcutionduprogramme:
locale::global(locale(""));
//Afficheladatecourante:
time_tdate;
time(&date);
structtm*TL=localtime(&date);
322
Chapitre16.Leslocales
use_facet<time_put<char>> (locale()).put(
cout,cout,,TL,c);
cout << endl;
//Afficheladateaveclafonctionstrftime
//delabibliothqueC:
chars[64];
strftime(s,64,"%c",TL);
cout << s << endl;
return0;
}
16.2.Lesfacettesstandards
Cettesectionprsentelensembledesfacettesstandardsdfiniesparlabibliothquestandard.
La
premirepartiedcritlarchitecturegnralelaquellelesfacettesstandardsseconforment,
etles
partiessuivantesdonnent unedescriptiondesprincipalesfonctionnalitsfourniesparchacunedes
catgoriesdefacettes.
16.2.1.Gnralits
Lesfacettesfourniesparlabibliothquestandardsontdesclasses template paramtresparletype
descaractressurlesquelsellestravaillent.Pourquelquesunesdecesfacettes,labibliothquestan
darddfinitunespcialisationpourlestypescharouwchar_t,spcialisationdontlebutestdoptimiser
lestraitementsdesfacettespourlesfluxdentre/sortiestandardssurcestypes.
Certainesdecesfacettesnesontutilisesquepourfournirdesinformationsauxautrespartiesdela
bibliothquestandardC++. Dautres, enrevanche, permettent deraliserlesoprationsdeforma
tageetdanalysesyntaxiquesurlesquelleslesfluxdentre/sortiesappuientpourimplmenterles
oprateurs operator<< et operator>>.Cesfacettesdisposentalorsdemthodes put et get qui
permettentdeffectuercesdeuxtypesdopration.
Lestraitementseffectusparlesfacettesdoiventprendreencomptelesparamtresdeleurlocaleain
siquelesoptionsdeformatagestockesdanslesfluxsurlesquelleslesentres/sortiesdoiventtre
effectues.Pourcela,lesfacettesdoiventdisposerdunmoyendercuprerlalocaledontellesfont
323
Chapitre16.Leslocales
partieoudontellesdoiventutiliserlesparamtres.Gnralement,lesfacettesquiralisentlesopra
tionsdentre/sortiepourlecomptedesfluxutilisentlamthodegetloc decesdernierspourobtenir
lalocaledontellesdoiventutiliserlesparamtres.Lesautresfacettesnepeuventpasprocderdela
mmemanire,carellesnedisposentpasforcmentdunobjetfluxpourdterminerlalocalecou
rante.Afindersoudreceproblme,labibliothquestandarddfinitdesclassesdefacettesdrives
etdontleconstructeurprendenparamtrelenomdelalocalelaquellecesfacettesappartiennent.
Cesclassessontdoncinitialises,dsleurconstruction,aveclenomdelalocaledanslaquelleelles
setrouvent,cequileurpermetventuellementdeffectuerdestraitementsdpendantsdecettelocale.
Lesnomsdecesclassesdefacettesdrivessontlesmmesqueceuxdeleursclassesdebase,
_byname .Parexemple,lafacettectype,qui,comme
ceciprsquilssontsuffixsparlachane
onleverraplusloin,permetdeclasserlescaractresselonleurnature,disposeduneclassedrive
ctype_bynamedontleconstructeurprendenparamtrelenomdelalocaledontlafacettefaitpartie.
Note:Lesimplmentationsdelabibliothquestandardfourniesaveclesenvironnementsde
dveloppementC++nesontpastenuesdefournircesfacettespourchaquelocaleexistantedans
lemonde.Enralit,quasimentaucunenvironnementnelefaitlheureactuelle.Enrevanche,
touteslesfacettesstandardsdoiventaumoinstrefourniesetfonctionnercorrectementavecles
locales "C" et "".
16.2.2.Lesfacettesdemanipulationdescaractres
Labibliothquestandarddfinitdeuxfacettespermettantdemanipulerlescaractres.
Lapremire
facette,lafacettectype,fournitlesfonctionspermettantdeclasserlescaractresendiffrentescat
gories.Cescatgoriescomprennentleslettres,leschiffres,lescaractresimprimables,lescaractres
graphiques,etc.Ladeuximefacettepermetquantelledeffectuerlesconversionsentrelesdiff
rentstypesexistantsdencodagedecaractres.Ilsagitdelafacettecode_cvt.
16.2.2.1.Lafacettectype
Lafacettectypedriveduneclassedebasedanslaquellesontdfinieslesdiffrentescatgoriesde
caractres.Cetteclasseestdclarecommesuitdanslentte locale :
classctype_base
{
public:
enummask
{
space=SPACE_VALUE,print=PRINT_VALUE,
cntrl=CNTRL_VALUE,alpha=ALPHA_VALUE,
digit=DIGIT_VALUE,xdigit=XDIGIT_VALUE,
324
Chapitre16.Leslocales
upper=UPPER_VALUE,lower=LOWER_VALUE,
punct=PUNCT_VALUE,
alnum=alpha|digit,graph=alnum|punct
};
};
Note:Commepourtouteslesfacettesstandards,lesmthodespubliquesdlguentleurtravail
desmthodesvirtuellesdclaresenzoneprotgedontlenomestceluidelamthodepublique
prfixparlachanedecaractresdo_ .Cesmthodespeuventtreredfiniesparlesclasses
drivesdelafacettectypeetfontdoncpartiedelinterfacedesfacettesstandards.Cependant,
325
Chapitre16.Leslocales
ellesnesontpasreprsentesdansladclarationdonnecidessusparsoucidesimplicit.Leur
smantiqueestexactementlammequecelledesmthodespubliquescorrespondantes.Nous
verronsdanslaSection16.3.2lamaniredeprocderpourredfinircertainesdesmthodesdes
facettesstandards.
326
Chapitre16.Leslocales
//Affichelersultat:
cout << tampon << endl;
delete[]tampon;
return0;
}
Note:Lesconversionseffectuesparlesmthodes narrow et widen netravaillentquavecles
reprsentationsdecaractresclassiquesdulangageC++.Celasignifiequelescaractressont
tousreprsentsparuneuniquevaleurdetypecharouwchar_t(cesmthodesnutilisentdonc
pasdereprsentationdescaractresbasessurdessquencesdecaractresdelongueurs
variables).Lamthode narrow delexempleprcdentcritdoncautantdecaractresdansle
tampondestinationquilyenadanslachaneconvertir.
Vousconstaterezquelutilisationdelamthode is pourdterminerlanaturedescaractrespeut
trerelativementfastidieuse,carilfautrcuprerlafacettectype,dterminerlavaleurdumasque
utiliser,puisappelerlamthode.Labibliothquestandarddfinitdoncuncertainnombredefonctions
globalesutilitairesdanslentte locale :
template
template
template
template
template
template
template
template
template
template
template
template
template
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
<classcharT>
boolisspace(charTc,constlocale&l)const;
boolisprint(charTc,constlocale&l)const;
booliscntrl(charTc,constlocale&l)const;
boolisupper(charTc,constlocale&l)const;
boolislower(charTc,constlocale&l)const;
boolisalpha(charTc,constlocale&l)const;
boolisdigit(charTc,constlocale&l)const;
boolispunct(charTc,constlocale&l)const;
boolisxdigit(charTc,constlocale&l)const;
boolisalnum(charTc,constlocale&l)const;
boolisgraph(charTc,constlocale&l)const;
charTtoupper(charTc,constlocale&l)const;
charTtolower(charTc,constlocale&l)const;
Lutilisationdecesfonctionsnedoitpasposerdeproblmeparticulier.Ellesprennenttoutesenpre
mierparamtrelecaractrecaractriseretendeuximeparamtrelalocaledontlafacettectype
doittreutilisepourralisercettecaractrisation.Chaquefonctionpermetdetesterlecaractrepour
lappartenancelunedescatgoriesdecaractresdfiniesdanslaclassedebasectype_base.Notez
cependantquesiungrandnombredecaractresdoiventtrecaractrisspourunemmelocale,ilest
plusperformantdobtenirlafacettectypedecettelocaleunebonnefoispourtoutesetdeffectuerles
appelslamthode is enconsquence.
Laclassectypetantuneclasse template,ellepeuttreutilisepournimportequeltypedecaractre
apriori. Toutefois, il est vident quecetteclassepeut treoptimisepourlestypesdecaractre
simples,ettoutparticulirementpourletypechar,parcequilnepeutpasprendreplusde256valeurs
diffrentes. Labibliothquestandarddfinit doncunespcialisationtotaledelaclasse template
ctypepourletypechar.Limplmentationdecettespcialisationsebasesuruntableaudevaleursde
typemaskindexeparlesvaleursquepeuventprendrelesvariablesdetypechar.Cetableaupermet
doncdedterminerrapidementlescaractristiquesdechaquecaractreexistant.Leconstructeurde
cettespcialisationdiffrelgrement duconstructeurdesaclasse template caril peut prendre
enparamtreunpointeursurcetableaudevaleursetunboolenindiquantsicetableaudoittre
dtruit automatiquement parlafacettelorsquelleest ellemmedtruiteounon. Ceconstructeur
prendgalemententroisimeparamtreunevaleurdetypeentierindiquant,commepourtoutesles
facettesstandards,silalocaledoitprendreenchargelagestiondeladuredeviedelafacetteounon.
327
Chapitre16.Leslocales
Lesautresmthodesdecettespcialisationsontidentiquesauxmthodesdelaclasse template de
baseetneserontdoncpasdcritesici.
16.2.2.2.Lafacettecodecvt
Lafacettecodecvtpermetderaliserlesoprationsdeconversiondunmodedereprsentationdes
caractresunautre.Engnral,eninformatique,lescaractressontcodspardesnombres.Letype
decesnombres,ainsiquelamaniredelesutiliser,peutvariergrandementdunereprsentationune
autre,etlesconversionspeuventnepassefairesimplement.Parexemple,certainesreprsentations
codentchaquecaractreavecunevaleuruniquedutypedecaractreutilis,maisdautrescodentles
caractressurdessquencesdelongueurvariable.Onnepeutdanscecasbienentendupasconver
tirdirectementunereprsentationenuneautre,carlinterprtationquelonpeutfairedesnombres
reprsentantlescaractresdpendducontextedterminparlesnombresdjlus.Lesoprationsde
conversionnesontdoncpastoujoursdirectes.
Deplus,danscertainsencodagestaillevariable,linterprtationdescaractrespeutdpendredes
caractresdjconvertis.Lafacettecodecvtmaintientdoncuntatpendantlesconversionsquelle
effectue, tat qui lui permet dereprendrelaconversiondunesquencedecaractresdanslecas
deconversionsralisesenplusieurspasses. Bienentendu, touslesencodagesnencessitent pas
forcmentlemaintiendunteltat.Cependant,certainslexigentetilfautdonctoujoursleprendre
encomptedanslesoprationsdeconversionsilonsouhaitequeleprogrammesoitportable.Pour
lessquencesdecaractresencodagevariableutilisantletypedecaractredebasechar,letypede
lavariabledtatpermettantdestockerltatcourantduconvertisseurestletypembstate_t.Dautres
typespeuventtreutilisspourlessquencesbasessurdestypesdecaractresdiffrentsdutype
char,maisengnral,touslesencodagestaillevariablesebasentsurcetype.Quoiquilensoit,
laclassecodecvtdfinituntypededonnecapabledestockerltatduneconversionpartielle.Ce
typeestletypestate_type,quipourradonctoujourstrercuprdanslaclassecodecvt.Lavariable
dtatduconvertisseurdevratresystmatiquementfournieauxmthodesdeconversiondelafacette
codecvt et devrabienentendutreinitialisesavaleurpardfaut audbut dechaquenouvelle
conversion.
Note:Lafacettecodecvt permet deraliserlesconversionsdunereprsentationdescarac
tresuneautre, maisnapaspour but dechanger lencodagedescaractres, cestdire
lassociationqui est faiteentrelessquencesdenombreset lescaractres. Celasignifieque
lafacettecodecvtpermetparexempledeconvertirdeschanesdecaractreslargeswchar_ten
squencesdelongueursvariablesdecaractresdetypechar,maisellenepermetpasdepasser
dunepagedecodesuneautre.
Lafacettecodecvtdriveduneclassedebasenommecodecvt_base. Cetteclassedfinitlesdif
frentsrsultatsquepeuventavoirlesoprationsdeconversion. Elleestdclarecommesuitdans
lentte locale :
classcodecvt_base
{
public:
enumresult
{
ok,partial,error,noconv
};
};
328
Chapitre16.Leslocales
Commevouspouvezleconstater,uneconversionpeutseralisercompltement(codedersultatok),
partiellementparmanquedeplacedanslasquencedestinationouparmanquededonnesenentres
(code partial),oupasdutout,soitenraisonduneerreurdeconversion(codederreurerror),soit
parcequaucuneconversionnestncessaire(codedersultat noconv).
Laclasse template codecvtellemmeestdfiniecommesuitdanslentte locale :
template <classinternT,classexternT,classstateT
>
classcodecvt:publiclocale::facet,publiccodecvt_base
{
public:
//Lestypesdedonnes:
typedefinternTintern_type;
typedefexternTextern_type;
typedefstateT state_type;
//Leconstructeur:
explicitcodecvt(size_trefs=0);
//Lesfonctionsdeconversion:
resultout(stateT&etat,constinternT*premier,
constinternT*dernier,constinternT*&suiv_source,
externT*dernier,externT*limite,externT*&suiv_dest)const;
resultin(stateT&etat,constexternT*premier,
constexternT*dernier,constexternT*&suiv_source,
internT*dernier,internT*limite,internT*&suiv_dest)const;
resultunshift(stateT&etat,
externT*dernier,externT*limite,externT*&suiv_dest)const;
intlength(conststateT&etat,
constexternT*premier,constexternT*dernier,size_tmax)const;
intmax_length()constthrow();
intencoding()constthrow();
boolalways_noconv()constthrow();
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
329
Chapitre16.Leslocales
Lesmthodes in et out permettentrespectivement,commeleurssignatureslindiquent,deraliser
lesconversionsentrelestypesinterneetexterneetviceversa.Ellesprennenttoutesdeuxseptpara
mtres.Lepremierparamtreestunerfrencesurlavariabledtatquidevratrefourniechaque
appellorsdeconversionssuccessivesdunmmefluxdedonnes.Cettevariableestdestinere
cevoirltatcourantdelaconversionetpermettraauxappelssuivantsdeconvertircorrectementles
caractressuivantsdufluxdentre.Lesdeuxparamtressuivantspermettentdespcifierlasquence
decaractresconvertir.Ilsdoiventcontenirlepointeursurledbutdelasquenceetlepointeursur
lecaractresuivantlederniercaractredelasquence.Lequatrimeparamtreestunparamtrede
retour,lafonctionluiaffecteralavaleurdupointeurolaconversionsestarrte.Uneconversion
peutsarrtercauseduneerreuroutoutsimplementparcequeletampondestinationnecontient
pasassezdeplacepouraccueilliruncaractredeplus.
Cepointeurpourratreutilisdansunap
pelultrieurcommepointeurdedpartaveclavaleurdelavariabledtatlissuedelaconversion
poureffectuerlasuitedecetteconversion.Enfin,lestroisderniersparamtresspcifientletampon
destinationdanslequellasquenceconvertiedoittrecrite.Ilspermettentdindiquerlepointeurde
dbutdecetampon, lepointeursuivantledernieremplacementutilisable, etunpointeurderetour
quiindiqueraladernirepositioncriteparloprationdeconversion.Cesdeuxmthodesrenvoient
unedesconstantesdelnumrationresultdfiniedanslaclassedebasecodecvt_basepourindiquer
commentlaconversionsesteffectue. Siaucuneconversionnestncessaire, lespointeurssurles
caractressuivantssontinitialisslavaleurdespointeursdedbutdesquenceetaucunecriture
nalieudansletampondestination.
Exemple163.Conversiondunechanedecaractreslargesenchaneencodagevariable
#include <iostream>
#include <string>
#include <locale>
usingnamespacestd;
intmain(void)
{
//Fixelalocaleglobale:
locale::global(locale(""));
//Lituneligne:
wstringS;
getline(wcin,S);
//Rcuprelafacettedeconversionverswchar_t:
constcodecvt<wchar_t,char,mbstate_t
> &f=
use_facet<codecvt<wchar_t,char,mbstate_t
>> (locale());
//Effectuelaconversion:
constwchar_t*premier=S.c_str();
constwchar_t*dernier=premier+S.length();
constwchar_t*suivant=premier;
strings;
chartampon[10];
char*fincvt=tampon;
codecvt_base::resultr;
mbstate_tetat=mbstate_t();
while(premier!=dernier)
{
//Convertitunmorceaudelachane:
r=f.out(etat,premier,dernier,suivant,
tampon,tampon+10,fincvt);
//Vrifieleserreurspossibles:
if(r==codecvt_base::ok||r==codecvt_base::partial)
330
Chapitre16.Leslocales
cout << "." << flush;
elseif(r==codecvt_base::noconv)
{
cout << "conversionnonncessaire"<< endl;
break;
}
elseif(r==codecvt_base::error)
{
cout << "erreur" << endl;
cout << suivantpremier << endl;
cout << fincvttampon << endl;
break;
}
//Rcuprelersultatetprparelaconversionsuivante:
s.append(tampon,fincvttampon);
premier=suivant;
}
cout << endl;
//Affichelersultat:
cout << s << endl;
return0;
}
Note:Silondsireeffectuerunesimpleconversiondunechanedecaractresdetypewchar_t
enchanedecaractresCclassique, onchercheraplutt utiliserlamthode narrow dela
facettectypeprsentedanslasectionprcdente.Eneffet,lafacettecodecvtutilise,apriori,
unesquencedecaractresavecunencodagetaillevariable,cequi necorrespondpasla
reprsentationdeschanesdecaractresCclassiques,pourlesquelleschaquevaleurdetype
charreprsenteuncaractre.
Il est possibledecomplterunesquencedecaractresencodagevariabledetellesortequela
variabledtatduconvertisseursoitrinitialise. Celapermetdeterminerunechanedecaractres
partiellement convertie, cequi enpratiquerevient complterlasquencedecaractresavecles
donnesquireprsenterontlecaractrenulterminal. Cetteoprationpeuttreraliselaidede
lamthode unshift delafacettecodecvt.Cettemthodeprendenparamtreunerfrencesurla
variabledtatduconvertisseur,ainsiquelespointeursdedbutetdefindutampondanslequelles
valeursajoutersontcrites.Ledernierparamtredelamthode unshift estunerfrencesurun
pointeurquirecevraladressesuivantcelleladernirevaleurcriteparlamthodesiloprationse
droulecorrectement.
Ilvadesoiqueladterminationdelalongueurdunechanedecaractresdontlescaractresont
unereprsentationtaillevariablenestpassimple.Lafacettecodecvtcomportedoncunemthode
length permettantdecalculer,ennombredecaractresdetypeintern_type,lalongueurdunes
quencedecaractresdetypeextern_type. Cettemthodeprendenparamtrelavariabledtatdu
convertisseurainsiquelespointeursspcifiantlasquencedecaractresdontlalongueurdoittre
calcule.Ledernierparamtreestlavaleurmaximalequelafonctionpeutretourner.Ellepermetde
limiterladterminationdelalongueurdelasquencesourceunebornemaximale,parexemplela
tailleduntampondestination. Lavaleurretourneestbienentendulalongueurdecettesquence
ou, autrementdit, lenombredevaleursdetypeintern_typencessairespourstockerlersultatde
laconversionquelamthode in feraitaveclesmmesparamtres. Dautrepart, ilestpossiblede
dterminerlenombremaximaldevaleursdetypeintern_typencessairespourreprsenterununique
caractrereprsentparunesquencedecaractresdetypeextern_type.Pourcela,ilsuffitdappeler
lamthode max_length delafacettecodecvt.
331
Chapitre16.Leslocales
Exemple164.Dterminationdelalongueurdunechanedecaractresencodagevariable
#include
#include
#include
#include
<iostream>
<string>
<locale>
<limits>
usingnamespacestd;
intmain(void)
{
//Fixelalocaleglobale:
locale::global(locale(""));
//Lituneligne:
strings;
getline(cin,s);
//Rcuprelafacettedeconversionverswchar_t:
constcodecvt<wchar_t,char,mbstate_t
> &f=
use_facet<codecvt<wchar_t,char,mbstate_t
>> (locale());
//Affichelalongueurdelachanedentre:
intl1=s.length();
//Calculelalongueurdelaligneenwchar_t:
mbstate_tetat=mbstate_t();
intl2=f.length(etat,s.c_str(),s.c_str()+l1,
numeric_limits<size_t>::max());
//Affichelesdeuxlongueurs:
cout << l1 << endl;
cout << l2 << endl;
return0;
}
Commeonladjindiqucidessus, touteslesreprsentationsdescaractresnesontpastaille
variableettouteslesreprsentationsnencessitentpasforcmentlutilisationdunevariabledtatde
typestate_type.Vouspouvezdterminerdynamiquementsilemodedereprsentationdescaractres
encoding.
dutypeintern_typeutiliseunencodagetaillevariableounonlaidedelamthode
Cettemthoderenvoie 1 silareprsentationdescaractresdetypeextern_typedpenddeltatdu
convertisseur,oulenombredecaractresdetypeextern_typencessairesaucodageduncaractrede
typeintern_typesicenombreestconstant.Silavaleurrenvoyeest 0,cenombrenestpasconstant,
mais,contrairementcequisepasselorsquelavaleurrenvoyeest 1,cenombrenedpendpasde
lavaleurdelavariabledtatduconvertisseur.
Enfin,certainsmodesdereprsentationdescaractressontcompatibles,voirefranchementidentiques.
in et out renvoienttoujours
Danscecas,jamaisaucuneconversionnestralise,etlesmthodes
noconv.Cestparexemplelecasdelaspcialisationcodecvt <char,char,mbstate_t> delafacette
codecvt. Vouspouvezdterminersi unefacetteeffectueradesconversionsounonenappelant la
mthode always_noconv.Elleretourne true sijamaisaucuneconversionneseferaetfalse sinon.
16.2.3.Lesfacettesdecomparaisondechanes
Leschanesdecaractressontgnralementclassesparordrealphabtique, ou, plusprcisment,
danslordrelexicographique.Lordrelexicographiqueestlordredfiniparlasquencedessymboles
lexicauxutiliss(cestdirelessymbolesutilisspourformerlesmotsdulangage,donc,enpratique,
leslettres, lesnombres, laponctuation, etc.). Cetordreestceluiquiestdfiniparlacomparaison
successivedescaractresdesdeuxchanescomparer,
lepremiercoupledecaractresdiffrents
332
Chapitre16.Leslocales
permettantdedonnerunjugementdeclassement.Ainsi,leschaneslespluspetitesausensdelordre
lexicographiquesontleschanesquicommencentparlespremierssymbolesdulexiqueutilis.Cette
maniredeprocdersupposebienentenduquelessymbolesutilisspourformerlesmotsdulexique
sontclasssdansunordrecorrect.Parexemple,ilfautquelalettre aapparaisseavantlalettre b,
quiellemmedoitapparatreavantlalettre c,etc.
Malheureusement,celanestpassisimple,carcetordrenestgnralementpasceluiutilisparles
pagesdecodesdunepart,etilexistetoujoursdessymbolesspciauxdontlaclassificationncessite
untraitementspcialdautrepart.Parexemple,lescaractresaccentussontgnralementplacsen
findepagedecodeetapparaissentdonclafindelordrelexicographique,cequiperturbeautoma
tiquementleclassementdeschanesdecaractrescontenantdesaccents.Demme,certaineslettres
sontenralitdescompositionsdelettresetdoiventtreprisesencompteentantquetellesdansles
oprationsdeclassement.Parexemple,lalettre doittreinterprtecommeun asuividun e.
Etquedireducasparticulierdesmajusculesetdesminuscules?
Commevouspouvezleconstater,ilnestpaspossibledesebaseruniquementsurlordredescarac
tresdansleurpagedecodepoureffectuerlesoprationsdeclassementdechanesdecaractres.De
plus,ilvadesoiquelordreutilispourclasserlessymboleslexicographiquesdpenddecessym
bolesetdoncdelalocaleutilis.Labibliothquestandardfournitdoncunefacetteprenantencompte
touscesparamtres:laclasse template collate.
Leprincipedefonctionnementdelafacettecollateestdetransformerleschanesdecaractresuti
lisantlesconventionsdelalocalelaquellelafacetteappartientenunechanedecaractresind
pendantedelalocale,comprenantventuellementdescodesdecontrlespciauxpourlescaractres
spcifiquescettelocale.Leschanesdecaractresainsitransformespeuventalorstrecompares
entreellesdirectement,aveclesmthodesdecomparaisonclassiquedechanesdecaractresquiuti
lisentlordrelexicographiquedujeudecaractresdulangageC.Latransformationesteffectuede
tellemanirequecettecomparaisonproduitlemmersultatquelacomparaisontenantcomptedela
localedeschanesdecaractresnontransformes.
Lafacettecollateestdclarecommesuitdanslentte locale :
template <classcharT>
classcollate:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefbasic_string<charT> string_type;
//Leconstructeur:
explicitcollate(size_trefs=0);
//Lesmthodesdecomparaisondechanes:
string_typetransform(constcharT*debut,constcharT*fin)const;
intcompare(constcharT*deb_premier,constcharT*fin_premier,
constcharT*deb_deuxieme,constcharT*fin_deuxieme)const;
longhash(constcharT*debut,constcharT*fin)const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
333
Chapitre16.Leslocales
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
334
Chapitre16.Leslocales
}
Note:Lamthode compare est trspratiquepourcomparerdeuxchanesdecaractresde
manireponctuelle.Cependant,onlui prfreralamthode transform si ungrandnombrede
comparaisonsdoit treeffectu. Eneffet, il est plussimpledetransformertoutesleschanes
decaractresunebonnefoispourtouteset
detravaillerensuitedirectement surleschanes
transformes.Cenestquelorsquelesoprationsdecomparaisonauronttterminesquelon
pourrarevenirsurleschanesdecaractresinitiales.Onviteainsi defairedestransformation
rptitiondeschanescompareretongagneainsi
beaucoupdetemps.Bienentendu,cela
ncessitedeconserverlassociationentreleschanesdecaractrestransformesetleschanes
decaractresinitiales, et doncdedoubler laconsommationmmoireduprogrammedueau
chanesdecaractrespendantletraitementdeceschanes.
Enfin,ilestcourantdechercherdtermineruneclefpourchaquechanedecaractres.Cetteclef
peuttreutilisepoureffectuerunerechercherapidedeschanesdecaractres. Lamthode hash
delafacettecollatepermetdecalculerunetelleclef,engarantissantquedeuxchanesdecaractres
identiquesausensdelamthode compare aurontlammevaleurdeclef.Onnoteracependantque
cetteclefnestpasunique,deuxchanesdecaractrespeuventavoirdeuxvaleursdeclefsidentiques
mmesilamthode compare renvoieunevaleurnonnulle.Cependant,cecasestextrmementrare,
etpermetdutilisermalgrtoutdesalgorithmesderechercherapide.Laseulechoselaquelleilfaut
faireattentionestquecesalgorithmesdoiventpouvoirsupporterlesclefsmultiples.
hash
Note:Lesclefsprobabilitderecouvrementfaiblecommecelleretourneparlamhtode
sontgnralementutilisesdanslesstructuresdedonnesappeles tables de hachage,cequi
expliquelenomdonncettemthode. Lestablesdehachagesont enralitdestableaux
delisteschanesindexsparlaclef dehachage(si lavaleurdelaclef dpasselatailledu
tableau, elleest ramenedansleslimitesdeceluici paruneoprationderduction). Cesont
desstructurespermettant derechercherrapidement desvaleurspourlesquellesunefonction
dehachagesimpleexiste. Cependant, ellessecomportent moinsbienquelesarbresbinaires
lorsquelenombredlmentsaugmente(quelquesmilliers).Onleurprfreradoncgnralement
lesassociationsdelabibliothquestandard, commelesmapet multimapparexemple. Vous
pouvezconsulterlabibliographiesivousdsirezobtenirplusderenseignementssurlestables
dehachageetlesstructuresdedonnesengnral.Lesassociationsetlesconteneursdela
bibliothquestandardserontdcritesdansleChapitre17.
16.2.4.Lesfacettesdegestiondesnombres
Lesoprationsdeformatageetlesoprationsdinterprtationdesdonnesnumriquesdpendentbien
entendudesconventionsnationalesdelalocaleinclusedanslesfluxquieffectuentcesoprations.En
ralit,cesoprationsnesontpasprisesenchargedirectementparlesflux,maispluttparlesfacettes
degestiondesnombres,quiregroupenttouteslesoprationspropresauxconventionsnationales.
Labibliothquestandarddfinit entout troisfacettesqui interviennent danslesoprationsde
formatage:unefacetteutilitaire,quicontientlesparamtresspcifiqueslalocale,etdeuxfacettes
ddiesrespectivementauxoprationsdelectureetauxoprationsdcrituredesnombres.
335
Chapitre16.Leslocales
16.2.4.1.Lafacettenum_punct
Lafacettequiregroupetouslesparamtresdelalocaleestlafacettenum_punct.
commesuitdanslentte locale :
Elleestdclare
template <classcharT>
classnumpunct:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefbasic_string<charT> string_type;
//Leconstructeur:
explicitnumpunct(size_trefs=0);
//Lesmthodesdelecturedesoptionsdeformatagedesnombres:
char_type
decimal_point() const;
char_type
thousands_sep() const;
string
grouping()
const;
string_type truename()
const;
string_type falsename()
const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
336
Chapitre16.Leslocales
Lesmthodes truename et falsename quantellespermettentauxfacettesdeformatagedobtenir
leschanesdecaractresquireprsententlesvaleurs true et false desboolens.Cesontceschanes
boolalpha atactivedanslesflux
decaractresquisontutiliseslorsqueloptiondeformatage
dentre/sortie.Lesvaleursretournesparcesmthodessont,pardfaut,lesmotsanglais true et
false.Ilestconcevabledansdautreslocales,cependant,davoirdesnomsdiffrentspourcesdeux
valeurs.NousverronsdanslaSection16.3.2lamaniredeprocderpourredfinircesmthodeset
construireainsiunelocalepersonnaliseetfrancise.
Note:Bienentendu, lesfacettesdcritureet delecturedesnombresutilisent galement les
optionsdeformatagequisontdfinisauniveaudesfluxdentre/sortie.Pourcela,lesoprations
dentre/sortiereoiventenparamtreunerfrencesurlefluxcontenantcesoptions.
16.2.4.2.Lafacettedcrituredesnombres
Lcritureetleformatagedesnombressontprisenchargeparlafacettenum_put.Cettefacetteest
dclarecommesuitdanslentte locale :
template <classcharT,
classOutputIterator=ostreambuf_iterator <charT>>
classnum_put:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefOutputIteratoriter_type;
//Leconstructeur:
explicitnum_put(size_trefs=0);
//Lesmthodesdcrituredesnombres:
iter_typeput(iter_types,ios_base&f,char_typeremplissage,boolv)const;
iter_typeput(iter_types,ios_base&f,char_typeremplissage,longv)const;
iter_typeput(iter_types,ios_base&f,char_typeremplissage,
unsignedlongv)const;
iter_typeput(iter_types,ios_base&f,char_typeremplissage,
doublev)const;
iter_typeput(iter_types,ios_base&f,char_typeremplissage,
longdoublev)const;
iter_typeput(iter_types,ios_base&f,char_typeremplissage,
void*v)const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
337
Chapitre16.Leslocales
Commevouspouvezleconstater,cettefacettedisposedunesurchargedelamthode put pourcha
cundestypesdebasedulangage.Cessurchargesprennentenparamtreunitrateurdcrituresur
lefluxdesortiesurlequellesdonnesformatesdevronttrecrites,
unerfrencesurlefluxde
sortiecontenantlesoptionsdeformatageutiliserlorsduformatagedesnombres, lecaractrede
remplissageutiliser,etbienentendulavaleurcrire.
Engnral,cesmthodessontappelesauseindesoprateursdinsertion operator<< pourchaque
typededonneexistant.Deplus,lefluxdesortiesurlequellescrituresdoiventtreeffectuesest
lemmequelefluxservantspcifierlesoptionsdeformatage, sibienquelappelauxmthodes
put estextrmementsimplifi.Nousverronsplusendtaillamaniredappelercesmthodesdans
laSection16.3.1,lorsquenouscrironsunenouvellefacettepourunnouveautypededonne.
16.2.4.3.Lafacettedelecturedesnombres
Lesoprationsdelecturedesnombrespartirdunfluxdedonnessontprisesenchargeparlafacette
num_get.Cettefacetteestdclarecommesuitdanslentte locale :
template <classcharT,
classInputIterator=istreambuf_iterator<charT>>
classnum_get:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefInputIteratoriter_type;
//Leconstructeur:
explicitnum_get(size_trefs=0);
//Lesmthodesdelecturedesnombres:
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,bool&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,long&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,unsignedshort&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,unsignedint&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,unsignedlong&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,float&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,double&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,longdouble&v)const;
iter_typeget(iter_typein,iter_typeend,ios_base&,
ios_base::iostate&err,void*&v)const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
338
Chapitre16.Leslocales
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
16.2.5.Lesfacettesdegestiondesmonnaies
Labibliothquestandardnedfinitpasdetypededonneddislareprsentationdesmontants.Elle
supposeeneffetquelesmontantssontstocksdansdesnombresvirguleflottantedanslaplupart
desprogrammesou,pourlesprogrammesquidsirentsaffranchirdeserreursdarrondisinvitables
lorsdelutilisationdeflottants,sousformetextuelledansdeschanesdecaractres.Enrevanche,la
bibliothquestandardfournit,toutcommepourlestypesstandards,deuxfacetteslocalisesprenant
encomptelalectureetlcrituredesmontants. Cesfacettessebasentgalementsurunetroisime
facettequiregroupetouslesparamtresspcifiquesauxconventionsnationales.
Note:Enralit,lesseulstypescapablesdereprsentercorrectementlesmontantseninfor
matiquesontlesentiersetlesnombresvirgulefixecodssurlesentiers. Eneffet, lestypes
intgrauxsontlesseulstypesquinesoulventpasdeproblmedereprsentationdesnombres
(conditionquil nyaitpasdedbordementsbienentendu)etlesnombresvirgulefixesont
particulirementadaptsauxmontants,carengnrallenombredechiffressignificatifsaprsla
virguleestfixpourunemonnaiedonne.Lesnombresvirguleflottantenepermettentpasde
reprsenterdesvaleursavecprcisionetintroduisentdeserreursincontrlablesdanslescalculs
etdanslesarrondis.Leschanesdecaractresquantellessouffrentdeleurlourdeuret,dans
laplupartdescas,delancessitdepasserpardesnombresvirguleflottantespourinterprter
leurvaleur. Lesfacettesprsentesdanscettesectionsont doncduneutilitrduitepourles
programmesqui cherchentobtenirdesrsultatsrigoureuxetprcis,etqui netolrentpasles
erreursdereprsentationetleserreursdarrondis.
339
Chapitre16.Leslocales
despcifiersilesfacettesdoiventtravailleraveclareprsentationinternationaledesmontantsounon.
Ilexisteeneffetunereprsentationuniverselledesmontantsqui,entreautresparticularits,utiliseles
codesinternationauxdemonnaie(USDpourledollaramricain,CANpourledollarcanadien,
EURpourleuro,etc.).
Commepourlesfacettesdegestiondesnombres, lesfacettesprenantenchargelesmonnaiessont
aunombredetrois.Unedecestroisfacettespermetdobtenirdesinformationssurlamonnaiedela
localeetlesdeuxautresralisentrespectivementlesoprationsdcritureetdelecturesurunflux.
16.2.5.1.Lafacettemoney_punct
Lafacettemoneypunctestlafacettepermettantauxdeuxfacettesdcritureetdelecturedesmontants
dobtenirlesinformationsrelativeslamonnaiedeleurlocale.Cettefacetteestdclarecommesuit
danslentte locale :
template <classcharT,boolInternational=false
>
classmoneypunct:publiclocale::facet,publicmoney_base
{
public:
//Lestypesdedonnes:
typedefcharTchar_type;
typedefbasic_string<charT> string_type;
//Leconstructeur:
explicitmoneypunct(size_trefs=0);
//Lesmthodesdelecturedesoptionsdeformatagedesmontants:
charT
decimal_point()const;
charT
thousands_sep()const;
string
grouping()
const;
int
frac_digits() const;
string_typecurr_symbol() const;
pattern
pos_format()
const;
pattern
neg_format()
const;
string_typepositive_sign()const;
string_typenegative_sign()const;
staticconstboolintl=International;
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
Commevouspouvezleconstater,cettefacettedisposedemthodespermettantdercuprerlesdi
verssymbolesquisontutilisspourcrirelesmontantsdelamonnaiequelledcrit.Ainsi,lamthode
decimal_point renvoielecaractrequidoittreutilisentantquesparateurduchiffredesuni
tsdelapartiefractionnairedesmontants, sicelleci doit trereprsente. Demme, lamthode
thousands_sep renvoielecaractrequidoittreutilispoursparerlesgroupesdechiffrespour
340
Chapitre16.Leslocales
lesgrandsmontants,etlamthode grouping renvoieunechanecontenant,danschacundesesca
ractres,lenombredechiffresdechaquegroupe.Cesmthodessontdoncsemblablesauxmthodes
correspondantesdelafacettenumpunct. Lenombredechiffressignificatifsaprslavirguleutilis
frac_digits. Cenestquesilavaleur
pourcettemonnaiepeuttreobtenuegrcelamthode
renvoyeparcettemthodeestsuprieure0quelesymboledesparationdesunitsdelapartie
fractionnairedelamthode decimal_point estutilis.
Lamthode curr_symbol permetdobtenirlesymbolemontairedelamonnaie.Cesymboledpend
delavaleurduparamtre templateInternational.Siceparamtrevaut true,lesymbolemo
ntairerenvoyseralesymbolemontaireinternational.Danslecascontraire,ceseralesymbolemo
ntaireenusagedanslepaysdecirculationdelamonnaie.Lavaleurduparamtre International
pourratreobtenugrcelaconstantestatique intl delafacette.
Lesmthodessuivantespermettentdespcifierleformatdcrituredesmontantspositifsetngatifs.
Cesmthodesutilisentlesdfinitionsdeconstantesetdetypesdelaclassedebasemoney_basedont
lafacettemoneypuncthrite.Laclassemoney_baseestdclarecommesuitdanslenttelocale :
classmoney_base
{
public:
enumpart
{
none,space,symbol,sign,value
};
structpattern
{
charfield[4];
};
};
Cetteclassecontientladfinitiondunenumrationdontlesvaleurspermettentdidentifierlesdif
frentescomposantesdunmontant,ainsiquunestructurepatternquicontientuntableaudequatre
caractres.Chacundecescaractrespeutprendrelunedesvaleursdelnumrationpart.Lastructure
patterndfinitdonclordredanslequellescomposantesdunmontantdoiventapparatre.Cesontdes
motifsdecegenrequisontrenvoysparlesmthodes pos_format et neg_format,quipermettent
dobtenirrespectivementleformatdesmontantspositifsetceluidesmontantsngatifs.
Lesdiffrentesvaleursquepeuventprendreleslmentsdumotifpatternreprsententchacuneune
partiedelexpressiondunmontant.Lavaleurvalue reprsentebienentendulavaleurdecemontant,
sign sonsigneet symbol lesymbolemontaire.Lavaleur space permetdinsrerunespacedans
lexpressiondunmontant,maislesespacesnepeuventpastreutilissendbutetenfindemontants.
Enfin,lavaleur none permetdenerienmettrelapositionoilapparatdanslemotif.
Lamaniredcrirelesmontantspositifsetngatifsvariegrandementselonlespays.
Engnral,
ilestcourantdutiliserlesigne poursignalerunmontantngatifetaucunsignedistinctifpour
lesmontantspositifs.Cependant,certainspayscriventlesmontantsngatifsentreparenthsesetla
marquedesmontantsngatifsnestdoncplusunsimplecaractre.Lesmthodes positive_sign
et negative_sign permettentdobtenirlessymbolesutiliserpournoterlesmontantspositifset
ngatifs.Ellesretournenttouteslesdeuxunechanedecaractres,dontlepremierestplacsystma
tiquementlemplacementauquellavaleur sign ataffectedanslachanedeformatrenvoye
parlesmthodes pos_format et neg_format.Lescaractresrsiduels,silsexistent,sontplacs
lafindelexpressiondumontantcompltementformate.Ainsi,dansleslocalespourlesquellesles
montantsngatifssontcritsentreparenthses,lachanerenvoyeparlamthode negative_sign
341
Chapitre16.Leslocales
est () , etpourleslocalesutilisantsimplementlesignengatif,
caractre .
cettechanenecontientquele
16.2.5.2.Lesfacettesdelectureetdcrituredesmontants
Lesfacettesdcritureet delecturedesmontantssont sansdoutelesfacettesstandardslesplus
simples. Eneffet, ellesnedisposent quedemthodespermettant dcrireet delirelesmontants
surlesflux.Cesfacettessontrespectivementlesfacettesmoney_putetmoney_get.Ellessontdfinies
commesuitdanslentte locale :
template <classcharT,boolIntl=false,
classOutputIterator=ostreambuf_iterator <charT>>
classmoney_put:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefOutputIterator
iter_type;
typedefbasic_string<charT> string_type;
//Leconstructeur:
explicitmoney_put(size_trefs=0);
//Lesmthodesdcrituredesmontants:
iter_typeput(iter_types,boolintl,ios_base&f,
char_typeremplissage,longdoubleunits)const;
iter_typeput(iter_types,boolintl,ios_base&f,
char_typeremplissage,conststring_type&digits)const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
template <classcharT,
classInputIterator=istreambuf_iterator<charT>>
classmoney_get:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefInputIterator
iter_type;
typedefbasic_string<charT> string_type;
//Leconstructeur:
explicitmoney_get(size_trefs=0);
//Lesmthodesdelecturedesmontants:
iter_typeget(iter_types,iter_typeend,boolintl,
ios_base&f,ios_base::iostate&err,
longdouble&units)const;
iter_typeget(iter_types,iter_typeend,boolintl,
ios_base&f,ios_base::iostate&err,
string_type&digits)const;
staticconstboolintl=Intl;
//Lidentificateurdelafacette:
342
Chapitre16.Leslocales
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
16.2.6.Lesfacettesdegestiondutemps
Labibliothquestandardnefournitquedeuxfacettespourlcritureetlalecturedesdates:lafacette
time_putetlafacettetime_get.Cesdeuxfacettesutilisentletypedebasestructtmdelabibliothque
Cpourreprsenterletemps.BienquecedocumentnedcrivepaslesfonctionsdelabibliothqueC,
ilestpeuttrebonderappelercommentlesprogrammesCmanipulentlesdatesengnral.
Lagestiondutempsdansunprogrammepeuttrsvitedevenirunvritablecauchemar,principalement
enraisondelacomplexitquelestreshumainssesontefforcsdedvelopperdansleurmanirede
reprsenterletemps.Eneffet,ilfauttenircomptenonseulementdesspcificitsdescalendriers(an
nesbissextilesounonparexemple), maisaussidesmultiplesbasesdenumrationutilisesdans
lcrituredesdates(24heuresparjour, 60minutesparheureet60secondesparminutes, puis10
diximesdansunesecondeetainsidesuite)etdesconventionslocalesdegestiondesheures(fuseau
horaire,heuredtetdhiver).Largledorlorsdelamanipulationdesdatesestdoncdetoujours
travaillerdansunrfrentieluniqueavecunereprsentationlinairedutemps,autrementdit,desim
plifiertoutcela.Enpratique,celarevientdirequelesprogrammesdoiventutiliserunereprsentation
linairedutemps(gnralement,lenombredesecondescoulesdepuisunedatederfrence)ettra
vaillerentempsuniversel.Demme,lestockagedesdatesdoittrefaitdansceformatafindegarantir
lapossibilitdchangerlesdonnessanspourautantlaisserlaplaceauxerreursdinterprtationde
cesdates.
Enpratique,labibliothqueCutiliseletypetime_t.Lesvaleursdecetypereprsententlenombre
dinstantscoulsdepuislepremierjanvier19700heure(dateconsidrecommeledbutdelre
informatiqueparlesinventeursdulangageC,KernighanetRitchie,etquelonappellecouramment
Epoch). LaduredecesinstantsnestpasnormaliseparlabibliothqueC, maisilsagitde
secondespourlessystmesPOSIX.Letypetime_tpermetdoncderaliserdescalculssimplement
surlesdates.Lesdatesreprsentesavecdestime_tsonttoujoursexprimesentempsuniversel.
343
Chapitre16.Leslocales
Bienentendu,ilexistedesfonctionspermettantdeconvertirlesdatescodessouslaformedetime_t
endateshumaineset rciproquement. Letypededonneutilispourstockerlesdatesauformat
humainestlastructurestructtm. Cettestructurecontientplusieurschamps, quireprsentententre
autreslanne,lejour,lemois,lesheures,lesminutesetlessecondes.Cetypecontientdonclesdates
auformatclatetpermetdobtenirlesdiffrentescomposantesdunedate.
Gnralement,lesdatessontformatesentempslocal,carlesutilisateursdsirentsouventavoirles
datesaffichesdansleurproprebasedetemps.Cependant,ilestgalementpossibledeformaterles
datesentempsuniversel.CesoprationsdeformatagessontralisesparlesbibliothquesCetC++,
etlesprogrammesnontdoncpassesoucierdesparamtresdefuseauxhoraires,dheuredtet
dhiveretdesconventionslocalesdcrituredesdates:toutestprisenchargeparleslocales.
Lesprincipalesfonctionspermettant demanipulerlesdatessont
dessous:
rcapitulesdansletableauci
Tableau161.FonctionsCdegestiondesdates
Fonction
Description
time_t
time(time_t*)
Permetdobtenirladatecourante.Peuttreappeleavecladressedune
variabledetypetime_tenparamtreouaveclaconstante NULL.Initialise
lavariablepasseparpointeuravecladatecourante,etrenvoiegalement
lavaleurcrite.
structtm
*gmtime(const
time_t*)
Permetdeconvertirunedatestockedansunevariabledetypetime_ten
saversionclateentempsuniversel.Lepointeurrenvoyrfrenceune
structurealloueenzonestatiqueparlabibliothqueCetnedoitpastre
libr.
structtm
*localtime(const
time_t*)
Permetdeconvertirunedatestockedansunevariabledetypetime_ten
saversionclateentempslocal.Lepointeurrenvoyrfrenceune
structurealloueenzonestatiqueparlabibliothqueCetnedoitpastre
libr.
time_t
mktime(structtm
*)
Permetdeconstruireunedatedetypetime_tpartirdunedateentemps
localstockedansunestructurestructtm.Lesdonnesmembresdela
structurestructtmpeuventtrecorrigesparlafonction mktime sibesoin
est.Cettefonctionestdonclafonctioninversede localtime.
size_t
strftime(char
*tampon,size_t
max,constchar
*format,constr
structtm*t)
Permetdeformaterunedatestockedansunestructurestructtmdansune
chanedecaractres.Cettechanedoittrefournieenpremierparamtre,
ainsiquelenombremaximaldecaractresquelafonctionpourracrire.
Lafonctionrenvoielenombredecaractrescritsou,silepremier
paramtreestnul,latailledelachanedecaractresquilfaudraitpour
effectuerunecriturecomplte.Lafonction strftime prenden
paramtreunechanedeformatetfonctionnedemaniresimilaireaux
fonctions printf et sprintf.Ellecomprendungrandnombrede
formats,maislesplusutilessontsansdoutelesformats %X et %x ,
quipermettentrespectivementdeformaterlheureetladateselonles
conventionsdelalocaleduprogramme.
Note:Il nexistepasdefonctionpermettantdeconvertirunedateexprimeentempsuniversel
et stockedansunestructurestructtmenunedatedetypetime_t. Demme, labibliothque
Cnefournitpasdefonctionpermettantdanalyserunechanedecaractresreprsentant une
date.Cependant,lanormeUnix98dfinitlafonctionstrptime,qui estlafonctioninversedela
344
Chapitre16.Leslocales
fonction strftime.
Lesfonctions localtime et gmtime nesontpassresdansunenvironnementmultithread.En
effet, lazonedemmoirerenvoyeest enzonestatiqueet est partagepartouslesthreads.
LabibliothqueCdfinitdoncdeuxfonctionscomplmentaires, localtime_r et gmtime_r,qui
prennent unparamtrecomplmentairequi doit recevoirunpointeursurlastructurestruct tm
danslequel lersultat doit trecrit. Cettestructureest alloueparlethreadappelant et ne
risquedoncpasdtredtruiteparunappellammefonctionparunautrethread.
LesfacettesdelabibliothquestandardC++nepermettentpasdemanipulerlesdatesensoi.
Ellesnesontdestinesquraliserleformatagedesdatesentenantcomptedesspcificits
dereprsentationdesdatesdelalocale. Ellessecomportent exactement commelafonction
strftime lefaitlorsquelonutiliseleschanesdeformat%X et %x .
16.2.6.1.Lafacettedcrituredesdates
Lafacettedcrituredesdatesestdclarecommesuitdanslentte locale :
template <classcharT,
classOutputIterator=ostreambuf_iterator <charT>>
classtime_put:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefOutputIteratoriter_type;
//Leconstructeur:
explicittime_put(size_trefs=0);
//Lesmthodesdcrituredesdates:
iter_typeput(iter_types,ios_base&f,char_typeremplissage,consttm*t,
charformat,charmodificateur=0)const;
iter_typeput(iter_types,ios_base&f,char_typeremplissage,consttm*t,
constcharT*debut_format,constcharT*fin_format)const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
Cettefacettedisposededeuxsurchargesdelamthodeput permettantdcrireunedatesurunfluxde
sortie.Lapremirepermetdcrireunedatesurlefluxdesortiedontunitrateurestdonnenpremier
paramtre.Leformatagedeladatesefaitcommeaveclafonction strftime delabibliothqueC.
Leparamtre modificateur nedoitpastreutilisengnral,sasignificationntantpasprcise
parlanormeC++.Ladeuximeformedelamthode put ralisegalementunecrituresurleflux,
enprenantcommechanedeformatlapremiresouschanecommenantparlecaractre %dansla
chaneindiqueparlesparamtres debut_format et fin_format.
345
Chapitre16.Leslocales
16.2.6.2.Lafacettedelecturedesdates
Lafacettedelecturedesdatespermetdelirelesdatesdanslemmeformatqueceluiutilisparla
%X ou %x . Cette
fonction strftime delabibliothqueClorsquelachanedeformatvaut
locale
facetteestdclarecommesuitdanslentte
:
template <classcharT,
classInputIterator=istreambuf_iterator<charT>>
classtime_get:publiclocale::facet,publictime_base
{
public:
//Lestypesdedonnes:
typedefcharT
char_type;
typedefInputIteratoriter_type;
//Leconstructeur:
explicittime_get(size_trefs=0);
//Lesmthodesdegestiondelalecturedesdates:
iter_typeget_time(iter_types,iter_typeend,ios_base&f,
ios_base::iostate&err,tm*t) const;
iter_typeget_date(iter_types,iter_typeend,ios_base&f,
ios_base::iostate&err,tm*t) const;
iter_typeget_weekday(iter_types,iter_typeend,ios_base&f,
ios_base::iostate&err,tm*t)const;
iter_typeget_monthname(iter_types,iter_typeend,ios_base&f,
ios_base::iostate&err,tm*t)const;
iter_typeget_year(iter_types,iter_typeend,ios_base&f,
ios_base::iostate&err,tm*t)const;
dateorderdate_order()const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
Lesdiffrentesmthodesdecettefacettepermettentrespectivementdobtenirlheure,ladate,lejour
delasemaine, lenomdumoiset lannedunedatedanslefluxdentrespcifiparlitrateur
fournienpremierparamtre.Toutescesdonnessontinterprtesenfonctiondelalocalelaquelle
lafacetteappartient.
Enfin,lamthode date_order permetdobtenirlunedesvaleursdelnumrationdfiniedansla
classedebasetime_baseetquiindiquelordredanslequellescomposantsjour/mois/annedes
datesapparaissentdanslalocaledelafacette.Laclassedebasetime_baseestdclarecommesuit
danslentte locale :
classtime_base
{
public:
enumdateorder
{
346
Chapitre16.Leslocales
no_order,dmy,mdy,ymd,ydm
};
};
Lasignificationdesdiffrentesvaleursdelnumrationestimmdiate.Laseulevaleurncessitant
desexplicationscomplmentairesestlavaleur no_order.Cettevaleurestrenvoyeparlamthode
date_order sileformatdedateutilisparlalocaledelafacettecontientdautreschampsquele
jour,lemoisetlanne.
Note:Lamthode date_order estfournieuniquementtitredefacilitparlabibliothquestan
dard.Ellepeutnepastreimplmentepourcertaineslocales.Danscecas,ellerenvoiesyst
matiquementlavaleur no_order .
16.2.7.Lesfacettesdegestiondesmessages
Afindefaciliterlinternationalisationdesprogrammes,labibliothquestandardfournitlafacettemes
sages,quipermetdeprendreenchargelatraductiondetouslesmessagesdunprogrammedemanire
indpendantedusystmesousjacent.Cettefacettepermetdexternalisertouslesmessagesdespro
grammesdansdesfichiersdemessagesquelonappelledescatalogues.Leformatetlemplacement
decesfichiersnesontpasspcifisparlanormeC++,cependant,lamaniredyaccdereststandar
diseetpermetdcriredesprogrammesportables.Ainsi,lorsquunprogrammedevratretraduit,il
suffiradetraduirelesmessagesstocksdanslesfichiersdecataloguepourchaquelangueetdeles
distribueravecleprogramme.
Note:Lamaniredecreretdinstallercesfichierstantspcifiquechaqueimplmentationde
labibliothquestandardet,dansunelargemesure,spcifiqueausystmedexploitationutilis,
cesfichiersneserontpasdcritsici.Seulelamaniredutiliserlafacettemessagesseradonc
indique.Reportezvousladocumentationdevotreenvironnementdedveloppementpourplus
dedtailssurlesoutilspermettantdegnrerlesfichiersdecatalogue.
Lafacettemessagesrfrencelesfichiersdecataloguelaideduntypededonnespcifique.Ce
typededonneestdfinidanslaclassedebasemessages_basecommetantuntypeintgral:
classmessages_base
{
public:
typedefintcatalog;
};
347
Chapitre16.Leslocales
typedefcharTchar_type;
typedefbasic_string<charT> string_type;
//Leconstructeur:
explicitmessages(size_trefs=0);
//Lesmthodesdegestiondescataloguesdemessages:
catalogopen(constbasic_string
<char> &nom,constlocale&l)const;
void
close(catalogc)const;
string_type get(catalogc,intgroupe,intmsg,
conststring_type&defaut)const;
//Lidentificateurdelafacette:
staticlocale::idid;
};
Note:Lesmthodesvirtuellesdimplmentationdesmthodespubliquesnontpastcrites
dansladclarationprcdenteparsoucidesimplification.Ellesexistentmalgrtout,etpeuvent
treredfiniesparlesclassesdrivesafindepersonnaliserlecomportementdelafacette.
348
Chapitre16.Leslocales
puisquelecontenudesmessagesestcritenclairdanslalanguepardfautdanslesfichiers
sourcesduprogramme.
16.3.Personnalisationdesmcanismesdelocalisation
Lesmcanismesdelocalisationonttconusdetellesortequeleprogrammeurpeut,silledsire(et
silenarellementlebesoin),personnaliserleurfonctionnement.Ainsi,ilestparfaitementpossible
dedfinirdenouvellesfacettes,parexemplepourpermettrelalocalisationdestypesdedonnescom
plmentairesdfinisparleprogramme.Demme,ilestpossiblederedfinirlesmthodesvirtuelles
desclassesdegestiondesfacettesstandardsdelabibliothqueetderemplacerlesfacettesoriginales
pardesfacettespersonnalises.Cependant,ilfautbienreconnatrequelamaniredeprocdernest
pastrspratique,etenfaitlesmcanismesinternesdegestiondesfacettessemblenttrerservsaux
classesetauxmthodesdelabibliothquestandardellemme.
16.3.1.Crationetintgrationdunenouvellefacette
CommeillatexpliqudanslaSection16.1,unefacettenestriendautrequuneclassedrivantde
laclasselocale::facetetcontenantunedonnemembrestatiqueid .Cettedonnemembreestutilise
parlesclassesdelocalepouridentifierletypedelafacetteetpourlintgrerdanslemcanismede
gestiondesfacettesstandards.
Lexemplesuivantmontrecommentonpeutraliserdeuxfacettespermettantdencapsulerlesspcifi
citsduntypededonnedfiniparleprogramme,letypeanswer_t.Cetypeestsuppospermettrela
crationdevariablescontenantlarponsedelutilisateurunequestion.Cenestriendautrequune
numrationcontenantlesvaleurs no (pourlarponsengative), yes (pourlaffirmative), all (pour
rpondreparlaffirmativepourtoutunensembledlments)et none (pourrpondreparlangative
pourtoutunensembledlments).
Danscet exemple, deuxfacettessont dfinies: lafacetteanswerpunct, qui prendenchargelalo
calisationdesnomsdesdiffrentesvaleursdelnumrationanswer_t,etlafacetteanswer_put,qui
prendenchargeleformatagedesvaleursdecettenumrationdansunfluxstandard.
Loprateur
operator<< estgalementdfini,afindeprsenterlamaniredontcesfacettespeuventtreutili
ses.Lafacetteanswer_getetloprateurcorrespondant operator>> nontpastdfinisetsont
laisssenexercicepourlelecteurintress.
Exemple166.Dfinitiondenouvellesfacettes
#include <iostream>
#include <locale>
usingnamespacestd;
//Nouveautypededonnepermettantdegrerlesrponses
//auxquestions(yes/no/all/none):
enumanswer_t
{
no,yes,all,none
};
//Facetteprenantdfinissantlesnomsdesrponses:
349
Chapitre16.Leslocales
template <classcharT>
classanswerpunct:publiclocale::facet
{
public:
//Lestypesdedonnes:
typedefcharTchar_type;
typedefbasic_string<charT> string_type;
//Lidentifiantdelafacette:
staticlocale::idid;
//Leconstructeur:
answerpunct(size_trefs=0):locale::facet(refs)
{
}
//Lesmthodespermettantdobtenirlesnomsdesvaleurs:
string_typeyesname()const
{
returndo_yesname();
}
string_typenoname()const
{
returndo_noname();
}
string_typeallname()const
{
returndo_allname();
}
string_typenonename()const
{
returndo_nonename();
}
protected:
//Ledestructeur:
virtual~answerpunct()
{
}
//Lesmthodesvirtuelles:
virtualstring_typedo_yesname()const
{
return"yes";
}
virtualstring_typedo_noname()const
{
return"no";
}
virtualstring_typedo_allname()const
{
return"all";
350
Chapitre16.Leslocales
}
virtualstring_typedo_nonename()const
{
return"none";
}
};
//Instanciationdelidentifiantdelafacetteanswerpunct:
template <classcharT>
locale::idanswerpunct<charT>::id;
//Facetteprenantenchargeleformatagedesrponses:
template <classcharT,
classOutputIterator=ostreambuf_iterator <charT>>
classanswer_put:publiclocale::facet
public:
//Lestypesdedonnes:
typedefcharTchar_type;
typedefOutputIterator
iter_type;
typedefbasic_string<charT> string_type;
//Lidentifiantdelafacette:
staticlocale::idid;
//Leconstructeur:
answer_put(size_trefs=0):locale::facet(refs)
{
}
//Lamthodedeformatagepublique:
iter_typeput(iter_typei,ios_base&flux,
char_typeremplissage,answer_tvaleur)const
{
returndo_put(i,flux,remplissage,valeur);
}
protected:
//Ledestructeur:
virtual~answer_put()
{
}
//Limplmentationdelamthodedeformatage:
virtualiter_typedo_put(iter_typei,ios_base&flux,
char_typeremplissage,answer_tvaleur)const
{
//Rcuprelafacettedcrivantlesnomsdetypes:
constanswerpunct<charT> &facet=
use_facet<answerpunct<charT>> (flux.getloc());
//Rcuprationdunomquiseracrit:
string_typeresult;
switch(valeur)
{
caseyes:
result=facet.yesname();
break;
351
Chapitre16.Leslocales
caseno:
result=facet.noname();
break;
caseall:
result=facet.allname();
break;
casenone:
result=facet.nonename();
break;
}
//crituredelavaleur:
constchar*p=result.c_str();
while(*p!=0)
{
*i=*p;
++i;++p;
}
returni;
}
};
//Instanciationdelidentifiantdelafacetteanswer_put:
template <classcharT,
classOutputIterator=ostreambuf_iterator <charT>>
locale::idanswer_put<charT,OutputIterator>::id;
//Oprateurpermettantdeformaterunevaleur
//detypeanswer_tdansunfluxdesortie:
template <classcharT,classTraits
>
basic_ostream<charT,Traits> &operator<<(
basic_ostream<charT,Traits> &flux,
answer_tvaleur)
{
//Initialisationdufluxdesortie:
typenamebasic_ostream<charT,Traits>::sentryinit(flux);
if(init)
{
//Rcuprationdelafacettedegestiondecetype:
constanswer_put<charT> &facet=
use_facet<answer_put<charT>> (flux.getloc());
//crituredesdonnes:
facet.put(flux,flux,,valeur);
}
returnflux;
}
intmain(void)
{
//Creunenouvellelocaleutilisantnosdeuxfacettes:
localetemp(locale(""),newanswerpunct
<char>);
localeloc(temp,newanswer_put <char>);
//Installecettelocaledanslefluxdesortie:
cout.imbue(loc);
//Affichequelquesvaleursdetypeanswer_t:
cout << yes << endl;
cout << no << endl;
cout << all << endl;
352
Chapitre16.Leslocales
cout << none << endl;
return0;
}
Note:Cetexemple,bienquedjcompliqu,passesoussilenceuncertainnombredepoints
quil faudrait thoriquementprendreencomptepourraliseruneimplmentationcorrectedes
facettesetdesoprateursdinsertionetdextractiondesdonnesdetypeanswer_tdanslesflux
standards.Ilfaudraiteneffettraiterlescasderreurslorsdescrituressurlefluxdesortiedansla
mthode do_put delafacetteanswer_put,capterlesexceptionsquipeuventseproduire,corriger
ltatdufluxdentre/sortieauseindeloprateuroperator<< etrelancercesexceptions.
Demme,lesparamtresdelalocalenesontabsolumentpasprisencomptedanslafacette
answerpunct,alorsquuneimplmentationcompltedevrait sensoucier. Pourcela, il faudrait
rcuprerlenomdelalocaleinclusedanslesfluxdentre/sortiedunepart,etdfinirunefacette
spcialiseanswerpunct_byname,enfonctiondunomdelaquellelesmthodes do_yesname ,
do_noname, do_allname et do_nonename devraientsadapter.Lasectionsuivantedonneunex
emplederedfinitiondunefacetteexistante.
16.3.2.Remplacementdunefacetteexistante
Laredfinitiondesmthodesdefacettesdjexistantesest lgrement plussimplequelcriture
dunenouvellefacette.Eneffet,ilnestplusncessairededfinirladonnemembrestatiqueid .De
plus,seuleslesmthodesquidoiventrellementtreredfiniesdoiventtrercrites.
Lexemplesuivantprsentecommentunprogrammepeutredfinirlesmthodes do_truename et
do_falsename delafacettestandard numpunct_byname afindenfourniruneversionlocaliseen
franais.Celapermetdutilisercesnomsfranaisdanslesoprationsdeformatagedesfluxdentre
/sortiestandards,lorsquelemanipulateur boolalpha atutilis.
Exemple167.Spcialisationdunefacetteexistante
#include
#include
#include
#include
<iostream>
<locale>
<clocale>
<cstring>
usingnamespacestd;
//Facettedestineremplacernumpunct_byname:
classMyNumpunct_byname:
publicnumpunct_byname<char>
{
//Lesnomsdesvaleurstrueetfalse:
constchar*m_truename;
constchar*m_falsename;
public:
MyNumpunct_byname(constchar*nom):
numpunct_byname<char>(nom)
{
//Dterminelenomdelalocaleactive:
constchar*loc=nom;
if(strcmp(nom,"")==0)
353
Chapitre16.Leslocales
{
//Rcuprelenomdelalocaleglobaleactive:
loc=setlocale(0,NULL);
}
//Prendenchargelesnomsfranais:
if(strcmp(loc,"fr_FR")==0)
{
m_truename="vrai";
m_falsename="faux";
}
else
{
//Pourlesautreslocales,utiliselesnomsanglais:
m_truename="true";
m_falsename="false";
}
}
protected:
~MyNumpunct_byname()
{
}
stringdo_truename()const
{
returnm_truename;
}
stringdo_falsename()const
{
returnm_falsename;
}
};
intmain(void)
{
//Fixelalocaleglobaleduprogramme:
locale::global(locale(""));
//Creunenouvellelocaleutilisantnotrefacette:
localel(locale(""),newMyNumpunct_byname(""));
//Installecettelocaledanslefluxdesortie:
cout.imbue(l);
//Affichedeuxboolens:
cout << boolalpha << true << endl;
cout << false << endl;
return0;
}
laclasse numpunct_byname
Note:LaclassedebasedelafacetteMyNumpunct_bynameest
parcequelafacetteabesoindeconnatrelenomdelalocalepourlaquelleelleestconstruite.
Eneffet,aucunautremcanismestandardnepermetunefacettedercuprercenometdonc
desadapterauxdiffrenteslocalesexistantes.Vousremarquerezquelesfacettesdeformatage
nontpasbesoindeconnatrecenompuisquellespeuventlercuprergrcelamthode name
delalocaledufluxsurlequelellestravaillent.
LafacetteMyNumpunct_bynameutiliselafonctionsetlocale delabibliothqueCpourrcuprer
lenomdelalocalecourantesi elleest initialiseavecunnomvide. Enralit, elledevrait
354
Chapitre16.Leslocales
rcuprercenomparsespropresmoyenset effectuerlestraductionsdesnomsdesvaleurs
true et false parellemme,carcelasupposequelalocaleglobaleduprogrammeestinitial
iseaveclemmenom.Cestpourcelaqueleprogrammeprincipal commenceparappelerla
mthode global delaclasselocal aveccommeparamtreunelocaleanonmyme.Celadit,les
mcanismespermettantunprogrammedercuprerlesparamtresdelalocaledfiniedans
lenvironnement dexcutionduprogrammesont spcifiqueschaquesystmeet nepeuvent
doncpastredcritsici.
Bienentendu,sidautreslanguesquelefranaisdevaienttreprisesencompte,dautremcan
ismesplusgnriquesdevraientgalementtremisenplacepourdfinirlesnomsdesvaleurs
true et false afindviterdecompliquerexagrmentlecodedelafacette.
355
Chapitre16.Leslocales
356
Chapitre17.Lesconteneurs
Laplupartdesprogrammesinformatiquesdoivent,unmomentdonnouunautre,conserverun
nombrearbitrairededonnesenmmoire,gnralementpouryaccderultrieurementetleurappli
querdestraitementsspcifiques.Engnral,lesstructuresdedonnesutilisessonttoujoursmani
pulespardesalgorithmesclassiques,quelonretrouvedoncsouvent,sicenestplusieursfois,dans
chaqueprogramme.Cesstructuresdedonnessontcommunmentappelesdesconteneursenraison
deleurcapacitcontenirdautresobjets.
Afindviterauxprogrammeursderinventersystmatiquementlaroueetdereprogrammerlesstruc
turesdedonnesetleursalgorithmesassocislesplusclassiques,labibliothquestandarddfinitun
certainnombredeclasses template pourlesconteneurslespluscourants.Cesclassessontparam
tresparletypedesdonnesdesconteneursetpeuventdonctreutilisesvirtuellementpourtoutes
lessituationsquiseprsentent.
Lesconteneursdelabibliothquestandardnesontpasdfinisparlesalgorithmesquilsutilisent,
maispluttparlinterfacequipeuttreutiliseparlesprogrammesclients.Labibliothquestandard
imposegalementdescontraintesdeperformancessurcesinterfacesentermesdecomplexit. En
ralit,cescontraintessonttoutsimplementlesplusfortesquisoient,cequigarantitauxprogrammes
quilesutilisentquilsaurontlesmeilleuresperformancespossibles.
Labibliothqueclassifielesconteneursendeuxgrandescatgoriesselonleursfonctionnalits:less
quencesetlesconteneursassociatifs.Unesquenceestunconteneurcapabledestockerseslments
demaniresquentielle,lesunslasuitedesautres.Leslmentssontdoncparfaitementidentifis
parleurpositiondanslasquence,etleurordrerelatifestdoncimportant.Lesconteneursassociatifs,
enrevanche, manipulentleursdonnesaumoyendevaleursquilesidentifientindirectement.
Ces
identifiantssontappelesdesclefsparanalogieaveclaterminologieutilisedanslesbasesdedon
nes.Lordrerelatifdeslmentsdansleconteneurestlaissdanscecaslalibrediscrtiondece
dernieretleurrecherchesefaitdonc,gnralement,parlintermdiairedeleursclefs.
Labibliothquefournitplusieursconteneursdechaquetype.Chacunasesavantagesetsesinconv
nients.Commeilnexistepasdestructurededonnesparfaitequipermettedobtenirlesmeilleures
performancessurlensembledesoprationsralisables,lutilisateurdesconteneursdelabibliothque
standarddevraeffectuersonchoixenfonctiondelutilisationquildsireenfaire.Parexemple,cer
tainsconteneurssont plusadaptslarecherchedlmentsmaissont relativement coteuxpour
lesoprationsdinsertionoudesuppression, alorsquepourdautresconteneurs, cest exactement
linverse.Lechoixdesconteneursutiliserseradoncdterminantquantauxperformancesfinalesdes
programmes.
17.1.Fonctionnalitsgnralesdesconteneurs
Auniveaudeleursinterfaces, touslesconteneursdelabibliothquestandardprsententdessimi
litudes. Cet tat defait nest pasdauhasard, maisbel et bienlavolontdesimplifierlavie
desprogrammeursenvitantdedfinirunemultitudedemthodesayantlammesignificationpour
chaqueconteneur.Cependant,malgrcettevolontduniformisation,ilexistedesdiffrencesentreles
diffrentstypesdeconteneurs(squencesouconteneursassociatifs).Cesdiffrencesproviennentes
sentiellementdelaprsenceduneclefdanscesderniers,quipermetdemanipulerlesobjetscontenus
plusfacilement.
Quellequesoitleurnature,lesconteneursfournissentuncertainnombredeservicesdebasequele
programmeurpeututiliser.Cesservicescomprennentladfinitiondesitrateurs,dequelquestypes
complmentaires,desoprateursetdefonctionsstandards.Lessectionssuivantesvousprsententces
357
Chapitre17.Lesconteneurs
fonctionnalitsgnrales.Toutefois,lesdescriptionsdonnesicineserontpasdtaillesoutremesure
carellesserontreprisesendtaildansladescriptiondechaqueconteneur.
17.1.1.Dfinitiondesitrateurs
Pour commencer, il vadesoi quetous les conteneurs delabibliothquestandarddisposent
ditrateurs. Commeonlavudans
laSection13.4, les itrateurs constituent uneabstraction
delanotiondepointeur
pour lestableaux. Ilspermettent doncdeparcourir tousleslments
dunconteneur squentiellement laidedeloprateur dedrfrencement * et deloprateur
dincrmentation ++.
Lesconteneursdfinissentdonctousuntypeiteratoretuntypeconst_iterator,quisontlestypesdes
itrateurssurleslmentsduconteneur.
Letypeditrateurconst_iteratorest dfini pouraccder
auxlmentsdunconteneurenlesconsidrantcommedesconstantes.Ainsi,siletypedeslments
stocksdansleconteneurestT,ledrfrencementdunconst_iteratorrenverraunobjetdetypeconst
T.
Lesconteneursdfinissentgalementlestypesdedonnesdifference_typeetsize_typequelonpeut
utiliserpoureffectuerdescalculsdarithmtiquedespointeursavecleursitrateurs.
Letypediffe
rence_typesedistinguedutypesize_typeparlefaitquilpeutcontenirtoutevaleurissuedeladif
frenceentredeuxitrateurs,etacceptedonclesvaleursngatives.Letypesize_typequantluiest
utilisplusspcialement pourcompterunnombredlments, et nepeut prendrequedesvaleurs
positives.
Afindepermettrelinitialisationdeleursitrateurs,lesconteneursfournissentdeuxmthodesbegin
et end,quirenvoientrespectivementunitrateurrfrenantlepremierlmentduconteneuretla
valeurdefindelitrateur,lorsquilapassledernierlmentduconteneur.Ainsi,leparcoursdun
conteneursefaittypiquementdelamaniresuivante:
//Obtientunitrateursurlepremierlment:
Conteneur::iterateuri=instance.begin();
//Bouclesurtouteslesvaleursdelitrateur
//jusquladernire:
while(i!=instance.end())
{
//Travaillesurllmentrfrencpari:
f(*i);
//Passellmentsuivant:
++i;
}
358
Chapitre17.Lesconteneurs
partirdeplusieursthreads, afinderendrevosprogrammesportablesversdautresenviron
nements.
LesitrateursutilissparlesconteneurssonttousaumoinsdutypeForwardIterator. Enpratique,
celasignifiequelonpeutparcourirlesitrateursdupremieraudernierlment,squentiellement.
Cependant,laplupartdesconteneursdisposentditrateursaumoinsbidirectionnels,etpeuventdonc
treparcourusdanslesdeuxsens. Lesconteneursquidisposentdecespropritssontappelsdes
conteneursrversibles.
Lesconteneursrversiblesdisposent,enplusdesitrateursdirects,ditrateursinverses.Cesitrateurs
sontrepectivementdetypereverse_iteratoretconst_reverse_iterator.Leurinitialisationpeuttrera
liselaidedelafonction rbegin,etleurvaleurdefinpeuttrercuprelaidedelafonction
rend.
17.1.2.Dfinitiondestypesdedonnesrelatifsauxobjets
contenus
Outrelestypesditrateurs,lesconteneursdfinissentgalementdestypesspcifiquesauxdonnes
quilscontiennent. Cestypesdedonnespermettent demanipulerlesdonnesdesconteneursde
maniregnrique,sansavoirdeconnaissanceprcisessurlanaturerelledesobjetsquilsstockent.
Ilssontdonccourammentutilissparlesalgorithmesdelabibliothquestandard.
Letyperellement utilispour stocker lesobjetsdansunconteneur nest pastoujoursletype
template utilispourinstancierceconteneur. Eneffet, certainsconteneursassociatifsstockent
lesclefsdesobjetsaveclavaleurdesobjetseuxmmes. Ilsutilisent pourcelalaclassepair, qui
permetdestocker,commeonlavuenSection14.2.2,descouplesdevaleurs.Letypedesdonnes
stockesparcesconteneursestdoncpluscomplexequelesimpletype template parlequelilssont
paramtrs.
Afindepermettreluniformisationdesalgorithmestravaillantsurcestypesdedonnes,lesconteneurs
dfinissent tousletypevalue_typedansleurclasse template. Cest enparticuliercetypequil
faut utiliserlorsdesinsertionsdlmentsdanslesconteneurs. Bienentendu, pourlaplupart des
conteneurs, etpourtouteslessquences, letypevalue_typeesteffectivementlemmetypequele
type template parlequellesconteneurssontparamtrs.
Lesconteneursdfinissent galement dautrestypespermettant demanipuler lesdonnesquils
stockent. Enparticulier, letypereferenceest letypedesrfrencessur lesdonnes, et letype
const_referenceestletypedesrfrencesconstantessurlesdonnes.Cestypessontutilissparles
mthodesdesconteneursquipermettentdaccderleursdonnes.
17.1.3.Spcificationdelallocateurmmoireutiliser
Touteslesclassestemplate desconteneursdelabibliothquestandardutilisentlanotiondallocateur
pourraliserlesoprationsdemanipulationdelammoirequellesdoiventeffectuerlorsdustockage
deleurslmentsoulorsdelapplicationdalgorithmesspcifiquesauconteneur.Letypedesallo
cateurspeuttrespcifidanslalistedesparamtres template desconteneurs, enmargedutype
desdonnescontenues.Lesconstructeursdesconteneursprennenttousunparamtredecetype,qui
seralallocateurmmoireutilispourceconteneur. Ainsi, ilestpossibledespcifierunallocateur
spcifiquepourchaqueconteneur,quipeuttreparticulirementoptimispourletypedesdonnes
gresparceconteneur.
359
Chapitre17.Lesconteneurs
Toutefois,leparamtretemplate spcifiantlaclassedelallocateurmmoireutiliserdisposedune
valeurpardfaut,quireprsentelallocateurstandarddelabibliothqueallocator <T>.Ilnestdonc
pasncessairedespcifiercetallocateurlorsdelinstanciationdunconteneur.Celarendplussimple
lutilisationdelabibliothquestandardC++pourceuxquinedsirentpasdveloppereuxmmeun
allocateurmmoire.Parexemple,ladclaration template duconteneurlistestlasuivante:
template <classT,classAllocator=allocator
<T>>
Ilestdoncpossibledinstancierunelistedentierssimplementennespcifiantqueletypedesobjets
contenus,enloccurrence,desentiers:
typedeflist<int> liste_entier;
Demme,leparamtredesconstructeurspermettantdespcifierlallocateurutiliserpourlesconte
neursdisposesystmatiquementdunevaleurpardfaut,quiestlinstancevidedutypedallocateur
spcifidanslalistedesparamtres template.Parexemple,ladclarationduconstructeurleplus
simpledelaclasselistestlasuivante:
template <classT,classAllocator>
list<T,Allocator>::list(constAllocator&=Allocator());
Ilestdoncparfaitementlgaldedclarerunelistedentiersimplementdelamaniresuivante:
liste_entierli;
la
Note:Il est peuttrebonderappelerquetouteslesinstancesdunallocateuraccdent
mmemmoire.Ainsi,il nestpasncessaire,engnral,deprciserlinstancedelallocateur
dansleconstructeurdesconteneurs.Eneffet,leparamtrepardfautfourniparlabibliothque
standardnestquuneinstanceparmi dautresqui permetdaccderlammoiregreparla
classedelallocateurfourniedanslalistedesparamtrestemplate .
Si vousdsirezspcifieruneclassedallocateurdiffrentedecelledelallocateurstandard,
vous
devrezfaireensortequecetteclasseimplmentetouteslesmthodesdesallocateursdelabibliothque
standard.LanotiondallocateuratdtailledanslaSection13.6.
17.1.4.Oprateursdecomparaisondesconteneurs
Les conteneurs disposent doprateurs de comparaison permettant dtablir des relations
dquivalenceoudesrelationsdordreentreeux.
Lesconteneurspeuvent toustrecomparsdirectement aveclesoprateurs == et !=. Larelation
dgalitentredeuxconteneursestdfinieparlerespectdesdeuxpropritssuivantes:
lesdeuxconteneursdoiventavoirlammetaille;
leurslmentsdoiventtreidentiquesdeuxdeux.
Siletypedesobjetscontenusdisposedesoprateursdinfrioritetdesuprioritsstrictes,lesmmes
oprateursserontgalementdfinispourleconteneur.Cesoprateursutilisentlordrelexicographique
360
Chapitre17.Lesconteneurs
pourdterminerleclassemententredeuxconteneurs.Autrementdit,loprateurdinfrioritcompare
leslmentsdesdeuxconteneursunun,etfixesonverdictdslapremirediffrenceconstate.Si
unconteneurestunsousensembledudeuxime,leconteneurlepluspetitestceluiquiestinclusdans
lautre.
Note:Remarquezqueladfinitiondesoprateursdecomparaisondinfrioritetdesuprior
itexistequel quesoitletypedesdonnesqueleconteneurpeutstocker.Cependant,comme
lesconteneurssont dfinissouslaformedeclasses template , cesmthodesnesont instan
ciesquesiellessonteffectivementutilisesdanslesprogrammes.Ainsi,ilestpossibledutiliser
lesconteneursmmesurdestypesdedonnespourlesquelslesoprateursdinfrioritetde
suprioritnesontpasdfinis.Cependant,cetteutilisationprovoquerauneerreurdecompilation,
carlecompilateurchercherainstancierlesoprateurscemoment.
17.1.5.Mthodesdintrtgnral
Enfin,lesconteneursdisposentdemthodesgnralespermettantdobtenirdesinformationssurleurs
proprits. Enparticulier, lenombredlmentsquilscontiennent peut tredtermingrcela
mthode size.Lamthode empty permetdedterminersiunconteneurestvideounon.Lataille
max_size.Pour
maximalequepeutprendreunconteneurestindiquequantelleparlamthode
finir,touslesconteneursdisposentdunemthode swap,quiprendenparamtreunautreconteneur
dummetypeetquiraliselchangedesdonnesdesdeuxconteneurs.Onutiliseradeprfrence
cettemthodetouteautretechniquedchangecarseuleslesrfrencessurlesstructuresdedonnes
desconteneurssontchangesaveccettefonction,cequigarantitunecomplexitindpendantedela
tailledesconteneurs.
17.2.Lessquences
Lessquencessontdesconteneursquiontprincipalementpourbutdestockerdesobjetsafindeles
traiterdansunordrebiendfini.Dufaitdelabsencedeclefpermettantdidentifierlesobjetsquelles
contiennent,ellesnedisposentdaucunefonctionderecherchedesobjets.Lessquencesdisposent
doncgnralementquedesmthodespermettantderaliserlinsertionetlasuppressiondlments,
ainsiqueleparcoursdeslmentsdanslordrequellesutilisentpourlesclasser.
17.2.1.Fonctionnalitscommunes
Ilexisteungrandnombredeclasses template desquencesdanslabibliothquestandardquiper
mettentdecouvrirlamajoritdesbesoinsdesprogrammeurs.Cesclassessontrelativementvaries
tantdansleursimplmentationsquedansleursinterfaces. Cependant, uncertainnombredefonc
tionnalitscommunessontgresparlaplupartdessquences.Cesontcesfonctionnalitsquecette
sectionseproposedevousdcrire.Lesfonctionnalitsspcifiqueschaqueclassedesquenceseront
dtaillessparmentdanslaSection17.2.2.1.
Lesexemplesfournisdanscettesectionsebaserontsurleconteneurlist,quiestletypedesquence
leplussimpledelabibliothquestandard.Cependant,ilssontparfaitementutilisablesaveclesautres
typesdesquencesdelabibliothquestandard, avecdesniveauxdeperformancesventuellement
diffrentsenfonctiondessquenceschoisiesbienentendu.
361
Chapitre17.Lesconteneurs
17.2.1.1.Constructionetinitialisation
Laconstructionet linitialisationdunesquencepeuvent sefairedemultiplesmanires. Less
quencesdisposenteneffetdeplusieursconstructeursetdedeuxsurchargesdelamthode assign
quipermetdeleuraffecteruncertainnombredlments. Leconstructeurleplussimpleneprend
aucunparamtre,hormisunallocateurstandardutiliserpourlagestiondelasquence,etpermet
deconstruireunesquencevide.Ledeuximeconstructeurprendenparamtrelenombredlments
initialdelasquenceetlavaleurdeceslments.Ceconstructeurpermetdoncdecrerunesquence
contenantdjuncertainnombredecopiesdunobjetdonn.Enfin,letroisimeconstructeurprend
deuxitrateurssuruneautresquencedobjetsquidevronttrecopisdanslasquenceencours
deconstruction. Ceconstructeurpeuttreutilispourinitialiserunesquencepartirduneautre
squenceoudunsousensembledesquence.
Lessurchargesdelamthode assign secomportentunpeucommelesdeuxderniersconstructeurs,
ceciprsquellesneprennentpasdallocateurenparamtre.Lapremiremthodepermetdoncde
rinitialiserlalisteetdelarempliravecuncertainnombredecopiesdunobjetdonn,etladeuxime
permetderinitialiserlalisteetdelarempliravecunesquencedobjetsdfiniepardeuxitrateurs.
Exemple171.Constructionetinitialisationduneliste
#include <iostream>
#include <list>
usingnamespacestd;
typedeflist<int> li;
voidprint(li&l)
{
li::iteratori=l.begin();
while(i!=l.end())
{
cout << *i << "";
++i;
}
cout << endl;
}
intmain(void)
{
//Initialiseunelisteavectroislmentsvalant5:
lil1(3,5);
print(l1);
//Initialiseuneautrelistepartirdelapremire
//(enfaitondevraitappelerleconstructeurdecopie):
lil2(l1.begin(),l1.end());
print(l2);
//Affecte4lmentsvalant2l1:
l1.assign(4,2);
print(l1);
//Affectel1l2(demme,ondevraitnormalement
//utiliserloprateurdaffectation):
l2.assign(l1.begin(),l1.end());
print(l2);
return0;
}
362
Chapitre17.Lesconteneurs
Bienentendu,ilexistegalementunconstructeuretunoprateurdecopiecapablesdinitialiserune
squencepartirduneautresquencedummetype.
Ainsi, il nest pasncessairedutiliserles
constructeursvusprcdemmentnilesmthodes assign pourinitialiserunesquencepartirdune
autresquencedemmetype.
17.2.1.2.Ajoutetsuppressiondlments
Linsertiondenouveauxlmentsdansunesquencesefaitnormalementlaidedelunedessur
chargesdelamthode insert.Bienentendu,ilexistedautresmthodesspcifiqueschaqueconte
neurdetypesquenceetquileursontplusappropries,
maiscesmthodesneserontdcritesque
danslessectionsconsacrescesconteneurs.Lesdiffrentesversionsdelamthode insert sont
rcapitulescidessous:
iteratorinsert(iteratori,value_typevaleur)
Permet dinsrerunecopiedelavaleurspcifieendeuximeparamtredansleconteneur.
Lepremierparamtreestunitrateurindiquantlendroitolenouvellmentdoittreins
r.Linsertionsefaitimmdiatementavantllmentrfrencparcetitrateur.Cettemthode
renvoieunitrateursurledernierlmentinsrdanslasquence.
voidinsert(iteratori,size_typen,value_typevaleur)
Permetdinsrer n copiesdellmentspcifientroisimeparamtreavantllmentrfrenc
parlitrateur i donnenpremierparamtre.
voidinsert(iteratori,iteratorpremier,iteratordernier)
Permetdinsrertousleslmentsdelintervalledfiniparlesitrateurs
avantllmentrfrencparlitrateur i.
premier et dernier
Exemple172.Insertiondlmentsdansuneliste
#include <iostream>
#include <list>
usingnamespacestd;
typedeflist<int> li;
voidprint(li&l)
{
li::iteratori=l.begin();
while(i!=l.end())
{
cout << *i << "";
++i;
}
cout << endl;
return;
}
intmain(void)
{
lil1;
363
Chapitre17.Lesconteneurs
//Ajoute5laliste:
li::iteratori=l1.insert(l1.begin(),5);
print(l1);
//Ajoutedeux3laliste:
l1.insert(i,2,3);
print(l1);
//Insrelecontenudel1dansuneautreliste:
lil2;
l2.insert(l2.begin(),l1.begin(),l1.end());
print(l2);
return0;
}
Lacomplexitdetoutescesmthodesdpenddirectementdutypedesquencesurlequelellessont
appliques. Lesavantageset lesinconvnientsdechaquesquenceseront dcritsdanslaSection
17.2.2.
17.2.2.Lesdiffrentstypesdesquences
Labibliothquestandardfournittroisclassesfondamentalesdesquence.Cestroisclassessontres
pectivement laclasselist, laclassevectoret laclassedeque. Chacunedecesclassespossdeses
spcificitsenfonctiondesquelleslechoixduprogrammeurdevrasefaire.Deplus,labibliothque
364
Chapitre17.Lesconteneurs
standardfournitgalementdesclassesadaptatricespermettantdeconstruiredesconteneursquiva
lents,maisdisposantduneinterfaceplusstandardetplushabituelleauxnotionscourammentutilises
eninformatique.Toutescesclassessontdcritesdanscettesection,lesadaptateurstantabordsen
dernirepartie.
17.2.2.1.Leslistes
Laclasse template listestcertainementlunedesplusimportantescar,commesonnomlindique,
elleimplmenteunestructuredelistechanedlments,cequiestsansdoutelunedesstructures
lesplusutiliseseninformatique. Cettestructureestparticulirementadaptepourlesalgorithmes
quiparcourentlesdonnesdansunordresquentiel.
Lespropritsfondamentalesdeslistessontlessuivantes:
ellesimplmententdesitrateursbidirectionnels.Celasignifiequilestfaciledepasserdunl
mentausuivantouauprcdent,maisquilnestpaspossibledaccderauxlmentsdelalistede
manirealatoire;
ellespermettentlinsertionetlasuppressiondunlmentavecuncotconstant,etsansinvalider
lesitrateursoulesrfrencessurleslmentsdelalisteexistants.Danslecasdunesuppression,
seulslesitrateursetlesrfrencessurleslmentssupprimssontinvalids.
Leslistesoffrentdonclaplusgrandesouplessepossiblesurlesoprationsdinsertionetdesuppres
siondeslments,encontrepartiedequoilesaccssontrestreintsunaccssquentiel.
Commelinsertionetlasuppressiondeslmentsentteetenqueuedelistepeuventsefairesans
recherche,cesontvidemmentlesoprationslespluscourantes.Parconsquent,laclasse template
listproposedesmthodesspcifiquespermettantdemanipulerleslmentsquisetrouventences
positions.Linsertiondunlmentpeutdonctreraliserespectivemententteetenqueuedeliste
aveclesmthodes push_front et push_back.Inversement,lasuppressiondeslmentssitusen
cesemplacementsestraliseaveclesmthodes pop_front et pop_back.Toutescesmthodesne
renvoientaucunevaleur,aussilaccsauxdeuxlmentssitusentteetenqueuedelistepeutiltre
ralisrespectivementparlintermdiairedesaccesseurs front et back,quirenvoienttousdeuxune
rfrence(ventuellementconstantesilalisteestellemmeconstante)surceslments.
Exemple173.Accslatteetlaqueueduneliste
#include <iostream>
#include <list>
usingnamespacestd;
typedeflist<int> li;
intmain(void)
{
lil1;
l1.push_back(2);
l1.push_back(5);
cout << "Tte:" << l1.front() << endl;
cout << "Queue:" << l1.back() << endl;
l1.push_front(7);
cout << "Tte:" << l1.front() << endl;
cout << "Queue:" << l1.back() << endl;
365
Chapitre17.Lesconteneurs
l1.pop_back();
cout << "Tte:" << l1.front() << endl;
cout << "Queue:" << l1.back() << endl;
return0;
}
Leslistesdisposentgalementdemthodesspcifiquesquipermettentdeleurappliquerdestraite
mentsquileursontpropres.Cesmthodessontdcritesdansletableaucidessous:
Tableau171.Mthodesspcifiquesauxlistes
Mthode
remove(constT
&)
Fonction
Permetdliminertousleslmentsdunelistedontlavaleurestgalela
valeurpasseenparamtre.Lordrerelatifdeslmentsquinesontpas
supprimsestinchang.Lacomplexitdecettemthodeestlinaireen
fonctiondunombredlmentsdelaliste.
remove_if(Predicat)Permetdliminertousleslmentsdunelistequivrifientleprdicatunaire
passenparamtre.Lordrerelatifdeslmentsquinesontpassupprimsest
inchang.Lacomplexitdecettemthodeestlinaireenfonctiondunombre
dlmentsdelaliste.
366
unique(Predicat)
Permetdliminertousleslmentspourlesquelsleprdicatbinairepassen
paramtreestvrifiaveccommevaleurllmentcourantetsonprdcesseur.
Cettemthodepermetdliminerlesdoublonssuccessifsdansunelisteselon
uncritredfiniparleprdicat.Parsoucidesimplicit,ilexisteunesurcharge
decettemthodequineprendpasdeparamtres,etquiutiliseunsimpletest
dgalitpourliminerlesdoublons.Lordrerelatifdeslmentsquinesont
passupprimsestinchang,etlenombredapplicationsduprdicatest
exactementlenombredlmentsdelalistemoinsunsilalistenestpasvide.
splice(iterator
position,list<T,
Allocator> liste,
iteratorpremier,
iterateurdernier)
Injectelecontenudelalistefournieendeuximeparamtredanslaliste
courantepartirdelapositionfournieenpremierparamtre.Leslments
injectssontleslmentsdelalistesourceidentifisparlesitrateurs
premier et dernier.Ilssontsupprimsdelalistesourcelavole.Cette
mthodedisposededeuxautressurcharges,lunenefournissantpasditrateur
dedernierlmentetquiinsreuniquementlepremierlment,etlautrene
fournissantaucunitrateurpourrfrencerleslmentsinjecter.Cette
derniresurchargeneprenddoncenparamtrequelapositionlaquelleles
lmentsdoiventtreinsrsetlalistesourceellemme.Danscecas,la
totalitdelalistesourceestinsreencetemplacement.Gnralement,la
complexitdesmthodes splice estproportionnelleaunombredlments
injects,saufdanslecasdeladerniresurcharge,quisexcuteavecune
complexitconstante.
sort(Predicat)
Trieleslmentsdelalistedanslordredfiniparleprdicatbinairede
comparaisonpassenparamtre.Encoreunefois,ilexisteunesurchargede
cettemthodequineprendpasdeparamtreetquiutiliseloprateur
dinfrioritpourcomparerleslmentsdelalisteentreeux.Lordrerelatif
deslmentsquivalents(cestdiredeslmentspourlesquelsleprdicatde
comparaisonnapaspustatuerdordrebiendfini)estinchanglissuede
loprationdetri.Onindiquesouventcettepropritendisantquecette
mthodeeststable.Lamthode sort sappliqueavecunecomplexitgale
Nln(N),o N estlenombredlmentsdelaliste.
Chapitre17.Lesconteneurs
Mthode
Fonction
merge(list<T,
Allocator>,
Predicate)
Injecteleslmentsdelalistefournieenpremierparamtredanslaliste
couranteenconservantlordredfiniparleprdicatbinairefourniendeuxime
paramtre.Cettemthodesupposequelalistesurlaquelleellesappliqueetla
listefournieenparamtresontdjtriesselonceprdicat,etgarantitquela
listersultanteseratoujourstrie.Lalistefournieenargumentestvide
lissuedelopration.Ilexistegalementunesurchargedecettemthodequi
neprendpasdesecondparamtreetquiutiliseloprateurdinfrioritpour
comparerleslmentsdesdeuxlistes.Lacomplexitdecettemthodeest
proportionnellelasommedestaillesdesdeuxlistesainsifusionnes.
reverse
Inverselordredeslmentsdelaliste.Cettemthodesexcuteavecune
complexitlinaireenfonctiondunombredlmentsdelaliste.
Exemple174.Manipulationdelistes
#include <iostream>
#include <functional>
#include <list>
usingnamespacestd;
typedeflist<int> li;
voidprint(li&l)
{
li::iteratori=l.begin();
while(i!=l.end())
{
cout << *i << "";
++i;
}
cout << endl;
return;
}
boolparity_even(inti)
{
return(i&1)==0;
}
intmain(void)
{
//Construitunelisteexemple:
lil;
l.push_back(2);
l.push_back(5);
l.push_back(7);
l.push_back(7);
l.push_back(3);
l.push_back(3);
l.push_back(2);
l.push_back(6);
l.push_back(6);
367
Chapitre17.Lesconteneurs
l.push_back(6);
l.push_back(3);
l.push_back(4);
cout << "Listededpart:" << endl;
print(l);
lil1;
//Listeenordreinverse:
l1=l;
l1.reverse();
cout << "Listeinverse:" << endl;
print(l1);
//Trielaliste:
l1=l;
l1.sort();
cout << "Listetrie:"
<< endl;
print(l1);
//Supprimetousles3:
l1=l;
l1.remove(3);
cout << "Listesans3:" << endl;
print(l1);
//Supprimelesdoublons:
l1=l;
l1.unique();
cout << "Listesansdoublon:" << endl;
print(l1);
//Retiretouslesnombrespairs:
l1=l;
l1.remove_if(ptr_fun(&parity_even));
cout << "Listesansnombrepair:"<< endl;
print(l1);
//Injecteuneautrelisteentreles7:
l1=l;
li::iteratori=l1.begin();
++i;++i;++i;
lil2;
l2.push_back(35);
l2.push_back(36);
l2.push_back(37);
l1.splice(i,l2,l2.begin(),l2.end());
cout << "Fusiondesdeuxlistes:"<< endl;
print(l1);
if(l2.size()==0)
cout << "l2estvide" << endl;
return0;
}
17.2.2.2.Lesvecteurs
Laclasse template vectordelabibliothquestandardfournitunestructurededonnesdontlas
mantiqueest prochedecelledestableauxdedonnesclassiquesdulangageC/C++.
Laccsaux
donnesdemanirealatoireestdoncralisableenuncotconstant,maislinsertionetlasuppres
siondeslmentsdansunvecteurontdesconsquencesnettementpluslourdesquedanslecasdes
listes.
Lespropritsdesvecteurssontlessuivantes:
368
Chapitre17.Lesconteneurs
lesitrateurspermettentlesaccsalatoiresauxlmentsduvecteur;
linsertionoulasuppressiondunlmentlafinduvecteursefaitavecunecomplexitconstante,
maislinsertionoulasuppressionentoutautrepointduvecteursefaitavecunecomplexitlinaire.
Autrementdit,lesoprationsdinsertionoudesuppressionncessitentaprioridedplacertousles
lmentssuivants,saufsillmentinsrousupprimsetrouveendernireposition;
danstouslescas,linsertiondunlmentpeutncessiterunerallocationdemmoire.Celaapour
consquencequengnral,lesdonnesduvecteurpeuventtredplacesenmmoireetqueles
itrateurset lesrfrencessurleslmentsdunvecteursont apriori invalidslasuitedune
insertion. Cependant, si aucunerallocationnalieu, lesitrateurset lesrfrencesnesont pas
invalidspourtousleslmentssitusavantllmentinsr;
lasuppressiondunlmentneprovoquantpasderallocation,seulslesitrateursetlesrfrences
surleslmentssuivantllmentsupprimsontinvalids.
Note:Notezbienquelesvecteurspeuventeffectuerunerallocationmmelorsquelinsertionse
faitendernireposition.Danscecas,lecotdelinsertionestbienentendutrslev.Toutefois,
lalgorithmederallocationutilisestsuffisamentvolupourgarantirquececotestconstant
enmoyenne(doncdecomplexitconstante).Autrementdit,lesrallocationsnesefontquetrs
rarement.
369
Chapitre17.Lesconteneurs
//Ajouteunlmentlafinduvecteur:
v.push_back(13);
//Affichelevecteurenutilisantloprateur[]:
for(inti=0;i <v.size();++i)
{
cout << v[i] << endl;
}
return0;
}
17.2.2.3.Lesdeques
Pourceuxquileslistesetlesvecteursneconviennentpas,labibliothquestandardfournitunconte
neurplusvoluquioffreunautrecompromisentrelarapiditdaccsauxlmentsetlasouplesse
danslesoprationsdajoutoudesuppression.Ilsagitdelaclasse template deque,quiimplmente
uneformedetamponcirculairedynamique.
Lespropritsdesdequessontlessuivantes:
lesitrateursdesdequespermettentlesaccsalatoiresleurslments;
linsertionetlasuppressiondeslmentsenpremireetendernirepositionsefaitavecuncot
constant.Noteziciquececotesttoujourslemme,etque,contrairementauxvecteurs,ilnesagit
pasduncotamorti(autrementdit,cenestpasunemoyenne).Enrevanche,toutcommepourles
vecteurs,linsertionetlasuppressionauxautrespositionssefaitavecunecomplexitlinaire;
contrairementauxvecteurs,touslesitrateursettouteslesrfrencessurleslmentsdeladeque
deviennentsystmatiquementinvalideslorsduneinsertionoudunesuppressiondlmentaux
autrespositionsquelapremireetladernire;
demme,linsertiondunlmentenpremireetdernirepositioninvalidetouslesitrateurssurles
lmentsdeladeque.Enrevanche,lesrfrencessurleslmentsrestentvalides.Remarquezque
lasuppressiondunlmentenpremireetendernirepositionnaaucunimpactsurlesitrateurs
etlesrfrencesdeslmentsautresqueceuxquisontsupprims.
370
Chapitre17.Lesconteneurs
Commeellepermetunaccsrapidetousseslments,laclasse template dequedisposedetoutes
lesmthodesdinsertionetdesuppressiondlmentsdeslistesetdesvecteurs.Outrelesmthodes
push_front, pop_front, push_back, pop_back etlesaccesseurs front et back,laclassedeque
dfinitdonclamthodeat,ainsiqueloprateurdaccsauxlmentsdetableaux[].Lutilisationde
cesmthodeseststrictementidentiquecelledesmthodeshomonymesdesclasses list et vector
etnedevraitdoncpasposerdeproblmeparticulier.
17.2.2.4.Lesadaptateursdesquences
Lesclassesdessquencesdebaselist,
vectoret dequesont supposessatisfairelaplupart des
besoinscourantsdesprogrammeurs.Cependant,labibliothquestandardfournitdesadaptateurspour
transformercesclassesendautresstructuresdedonnesplusclassiques.Cesadaptateurspermettent
deconstruiredespiles,desfilesetdesfilesdepriorit.
17.2.2.4.1. Les piles
Lespilessontdesstructuresdedonnesquisecomportent,commeleurnomlindique,commeun
empilementdobjets.Ellesnepermettentdoncdaccderquauxlmentssitusenhautdelapile,
etlarcuprationdeslmentssefaitdanslordreinversedeleurempilement.
Enraisondecette
proprit,onlesappellegalementcourammentLIFO,acronymedelanglaisLastInFirstOut
(dernierentr,premiersorti).
LaclasseadaptatricedfinieparlabibliothquestandardC++pourimplmenterlespilesestlaclasse
template stack.Cetteclasseutilisedeuxparamtres template :letypedesdonnesluimmeetle
typeduneclassedesquenceimplmentantaumoinslesmthodes back, push_back et pop_back.
Ilestdoncparfaitementpossibledutiliserleslistes,dequesetvecteurspourimplmenterunepile
laidedecetadaptateur.Pardfaut,laclassestackutiliseunedeque,etilnestdoncgnralementpas
ncessairedespcifierletypeduconteneurutiliserpourraliserlapile.
Linterfacedespilesserduitaustrictminimum,puisquellesnepermettentdemanipulerqueleur
sommet.Lamthode push permetdempilerunlmentsurlapile,etlamthodepop delenretirer.
Cesdeuxmthodesnerenvoientrien,laccsllmentsituausommetdelapilesefaitdoncpar
lintermdiairedelamthode top.
Exemple176.Utilisationdunepile
#include <iostream>
#include <stack>
usingnamespacestd;
intmain(void)
{
typedefstack<int> si;
//Creunepile:
sis;
//Empilequelqueslments:
s.push(2);
s.push(5);
s.push(8);
//Afficheleslmentsenordreinverse:
while(!s.empty())
{
cout << s.top() << endl;
371
Chapitre17.Lesconteneurs
s.pop();
}
return0;
}
372
Chapitre17.Lesconteneurs
17.2.2.4.3. Les files de pr iorits
Enfin,labibliothquestandardfournitunadaptateurpermettantdimplmenterlesfilesdepriorits.
Lesfilesdeprioritsressemblentauxfilesclassiques,maisnefonctionnentpasdelammemanire.
Eneffet, contrairement auxfilesnormales, llment qui setrouveenpremirepositionnest pas
toujourslepremierlment qui atplacdanslafile, maiscelui qui disposedelaplusgrande
valeur.Cestcettepropritquiadonnsonnomauxfilesdepriorits,carlaprioritdunlmentest
icidonneparsavaleur.Bienentendu,labibliothquestandardpermetlutilisateurdedfinirson
propreoprateurdecomparaison,afindeluilaisserspcifierlordrequilveututiliserpourdfinirla
prioritdeslments.
Note:Onprendragardeaufaitquelabibliothquestandardnimposepasauxfilesdepriorits
desecomportercommedesfilesclassiquesavecleslmentsdeprioritsgales.Celasignifie
quesiplusieurslmentsdeprioritgalesontinsrsdansunefiledepriorit,ilsnensortiront
pasforcmentdanslordredinsertion.Onditgnralementquelesalgorithmesutilissparles
filesdeprioritsnesontpas stablespourtraduirecetteproprit.
373
Chapitre17.Lesconteneurs
booloperator()(constA&a1,constA&a2)
{
returna1.k < a2.k;
}
};
intmain(void)
{
//Construitquelquesobjets:
Aa1(1,"Prioritfaible");
Aa2(2,"Prioritmoyenne1");
Aa3(2,"Prioritmoyenne2");
Aa4(3,"Priorithaute1");
Aa5(3,"Priorithaute2");
//Construitunefiledepriorit:
priority_queue<A,vector<A>,C > pq;
//Ajouteleslments:
pq.push(a5);
pq.push(a3);
pq.push(a1);
pq.push(a2);
pq.push(a4);
//Rcupreleslmentsparordredepriorit:
while(!pq.empty())
{
cout << pq.top().t << endl;
pq.pop();
}
return0;
}
Note:Enraisondelancessitderorganiserlordreduconteneursousjacentchaqueajout
ousuppressiondunlment, lesmthodes push et pop sexcutent avecunecomplexiten
ln(N),o N estlenombredlmentsprsentsdanslafiledepriorit.
Lesfilesdeprioritutilisenteninternelastructuredetas,quelondcriradanslechapitretraitant
desalgorithmesdelabibliothquestandardlasectionSection18.3.1.
17.3.Lesconteneursassociatifs
Contrairementauxsquences, lesconteneursassociatifssontcapablesdidentifierleurslments
laidedelavaleurdeleurclef.Grcecesclefs,lesconteneursassociatifssontcapablesdeffectuer
desrecherchesdlmentsdemanireextrmementperformante.Eneffet,lesoprationsderecherche
sefontgnralementavecuncotlogarithmiqueseulement, cequirestegnralementraisonnable
mmelorsquelenombredlmentsstocksdevientgrand.Lesconteneursassociatifssontdoncpar
ticulirementadaptslorsquonabesoinderaliserungrandnombredoprationderecherche.
Labibliothquestandarddistinguedeuxtypesdeconteneursassociatifs:lesconteneursquidiffren
cientlavaleurdelaclefdelavaleurdelobjetluimmeetlesconteneursquiconsidrentqueles
objetssontleurpropreclef.Lesconteneursdelapremirecatgorieconstituentcequelonappelle
374
Chapitre17.Lesconteneurs
desassociationscarilspermettentdassocierdesclefsauxvaleursdesobjets.Lesconteneursassocia
tifsdeladeuximecatgoriesontappelsquanteuxdesensembles,enraisondufaitquilsservent
gnralementindiquersiunobjetfaitpartieounondunensembledobjets.Onnesintressedans
cecaspaslavaleurdelobjet,puisquonlaconnatdjsiondisposedesaclef,maispluttson
appartenanceounonunensembledonn.
Sitouslesconteneursassociatifsutilisentlanotiondeclef,
tousnesecomportentpasdemanire
identiquequantlutilisationquilsenfont.Pourcertainsconteneurs,quelonqualifiedeconteneurs
clefsuniques,chaquelmentcontenudoitavoiruneclefquiluiestpropre.Ilestdoncimpos
sibledinsrerplusieurslmentsdistinctsaveclammeclefdanscesconteneurs.Enrevanche,les
conteneursassociatifditsclefsmultiplespermettentlutilisationdunemmevaleurdeclefpour
plusieursobjetsdistincts.Loprationderecherchedunobjetpartirdesaclefpeutdonc,dansce
cas,renvoyerplusdunseulobjet.
Labibliothquestandardfournitdoncquatretypesdeconteneursautotal,selonquecesontdesas
sociationsoudesensembles,etselonquecesontdesconteneursassociatifsclefsmultiplesounon.
Lesassociationsclefsuniquesetclefsmultiplesontimplmentesrespectivementparlesclasses
template mapet multimap, et lesensemblesclefsuniqueset clefsmultiplesparlesclasses
template setetmultiset.Cependant,bienquecesclassessecomportentdemanireprofondment
diffrentes, ellesfournissentlesmmesmthodespermettantdelesmanipuler. Lesconteneursas
sociatifssont doncmoinshtroclitesquelessquences, et leurmanipulationenest debeaucoup
facilite.
Lessectionssuivantesprsententlesdiffrentesfonctionnalitsdesconteneursassociatifsdansleur
ensemble.Lesexemplesserontdonnsenutilisantlaplupartdutempslaclasse template map,car
cestcertainementlaclasselaplusutiliseenpratiqueenraisondesacapacitstockeretretrouver
rapidementdesobjetsidentifisdemanireuniqueparunidentifiant.Cependant,certainsexemples
utiliserontdesconteneursclefsmultiplesafindebienmontrerlesraresdiffrencesquiexistententre
lesconteneursclefsuniquesetlesconteneursclefsmultiples.
17.3.1.Gnralitsetpropritsdebasedesclefs
Lacontraintefondamentalequelesalgorithmesdesconteneursassociatifsimposentestquilexiste
unerelationdordrepourletypededonneutilispourlesclefsdesobjets.Cetterelationpeuttre
dfiniesoitimplicitementparunoprateurdinfriorit,soitparunfoncteurquelonpeutspcifier
entantqueparamtre template desclassesdesconteneurs.
Alorsquelordredelasuitedeslmentsstocksdanslessquencesesttrsimportant,cenestpasle
casaveclesconteneursassociatifs,carceuxcisebasentexclusivementsurlordredesclefsdesobjets.
Enrevanche,labibliothquestandardC++garantitquelesensdeparcoursutilisparlesitrateurs
desconteneursassociatifsestnondcroissantsurlesclefsdesobjetsitrs.Celasignifiequeletest
dinfrioritstrictentrelaclefdellmentsuivantetlaclefdellmentcourantesttoujoursfaux,
ou,autrementdit,llmentsuivantnestpaspluspetitquellmentcourant.
Note:Attention,celanesignifieaucunementqueleslmentssontclasssdanslordrecroissant
desclefs. Eneffet, lexistencedunoprateurdinfrioritnimpliquepasforcment celledun
oprateurdesuprioritdunepart,etdeuxvaleurscomparablesparcetoprateurnelesontpas
forcmentparloprateurdesupriorit.Llmentsuivantnestdoncpasforcmentplusgrand
quellment courant. Enparticulier, pourlesconteneursclefsmultiples, lesclefsdedeux
lmentssuccessifspeuventtregales.
Enrevanche,leclassementutilisparlesitrateursdesconteneursclefsuniquesestplusfort,
puisquedanscecas,onnapassesoucierdesclefsayantlammevaleur.Lasquencedes
valeursitresest donccettefoisstrictement croissante, cestdirequelaclef dellment
courantesttoujoursstrictementinfrieurelaclefdellmentsuivant.
375
Chapitre17.Lesconteneurs
Commepourtouslesconteneurs,letypedeslmentsstocksparlesconteneursassociatifsestletype
value_type.Cependant,contrairementauxsquences,cetypenestpastoujoursletypetemplate par
lequelleconteneurestparamtr.Eneffet,cetypeestunepairecontenantlecoupledevaleursform
parlaclefetparlobjetluimmepourtouteslesassociations(cestdirepourlesmapetlesmulti
map).Danscecas,lesmthodesduconteneurquidoiventeffectuerdescomparaisonssurlesobjets
sebasentuniquementsurlechamp first delapaireencapsulantlecouple(clef,valeur)dechaque
objet.Autrementdit,lescomparaisonsdobjetssonttoujoursdfiniessurlesclefs,etjamaissurles
objetseuxmmes.Bienentendu,pourlesensembles,letypevalue_typeeststrictementquivalentau
type template parlequelilssontparamtrs.
Poursimplifierlutilisationdeleursclefs,lesconteneursassociatifsdfinissentquelquestypescom
plmentairesdeceuxquelonadjprsentsdanslaSection17.1.2.Leplusimportantdecestypes
estsansdouteletypekey_typequi,commesonnomlindique,reprsenteletypedesclefsutilises
parceconteneur. Cetypeconstituedonc, avecletypevalue_type, lessentiel desinformationsde
typagedesconteneursassociatifs.Enfin,lesconteneursdfinissentgalementdestypesdeprdicats
permettantdeffectuerdescomparaisonsentredeuxclefsetentredeuxobjetsdetypevalue_type.Il
sagitdestypeskey_compareetvalue_compare.
17.3.2.Constructionetinitialisation
Lesconteneursassociatifsdisposentdeplusieurssurchargesdeleursconstructeursquipermettentde
lescreretdelesinitialiserdirectement.Demaniregnrale,cesconstructeursprennenttousdeux
paramtresafindelaisserauprogrammeurlapossibilitdedfinirlavaleurdufoncteurquilsdoivent
utiliserpourcomparerlesclefs, ainsiquuneinstancedelallocateurutiliserpourlesoprations
mmoire.Commepourlessquences,cesparamtresdisposentdevaleurspardfaut,sibienquen
gnralilnestpasncessairedelesprciser.
Hormisleconstructeurdecopieetleconstructeurpardfaut,lesconteneursassociatifsfournissent
untroisimeconstructeurpermettantdelesinitialiserpartirdunesriedobjets.
Cesobjetssont
spcifispardeuxitrateurs,lepremierindiquantlepremierobjetinsrerdansleconteneuretle
deuximelitrateurrfrenant llment suivant ledernierlment insrer. Lutilisationdece
constructeurestsemblableauconstructeurdummetypedfinipourlessquencesetnedevraitdonc
pasposerdeproblmeparticulier.
Exemple179.Constructionetinitialisationduneassociationsimple
#include <iostream>
#include <map>
#include <list>
usingnamespacestd;
intmain(void)
{
typedefmap<int,char* > Int2String;
//Remplitunelistedlmentspourcesmaps:
typedeflist<pair<int,char* >> lv;
lvl;
l.push_back(lv::value_type(1,"Un"));
l.push_back(lv::value_type(2,"Deux"));
l.push_back(lv::value_type(5,"Trois"));
l.push_back(lv::value_type(6,"Quatre"));
376
Chapitre17.Lesconteneurs
//Construitunemapetlinitialiseaveclaliste:
Int2Stringi2s(l.begin(),l.end());
//Affichelecontenudelamap:
Int2String::iteratori=i2s.begin();
while(i!=i2s.end())
{
cout << i>second << endl;
++i;
}
return0;
}
Note:Contrairementauxsquences,lesconteneursassociatifsnedisposentpasdemthode
assign permettantdinitialiserunconteneuravecdesobjetsprovenantdunesquenceoudun
autreconteneurassociatif. Enrevanche, ilsdisposent dunconstructeuret dunoprateurde
copie.
17.3.3.Ajoutetsuppressiondlments
Dufaitdelexistencedesclefs,lesmthodesdinsertionetdesuppressiondesconteneursassociatifs
sontlgrementdiffrentesdecellesdessquences.Deplus,ellesnontpastoutfaitlammesigni
fication.Eneffet,lesmthodesdinsertiondesconteneursassociatifsnepermettentpas,contrairement
cellesdessquences,despcifierlemplacementounlmentdoittreinsrpuisquelordredes
lmentsestimposparlavaleurdeleurclef.
Lesmthodesdinsertiondesconteneursassociatifs
sontprsentescidessous:
iteratorinsert(iteratori,constvalue_type&valeur)
Insreoutentedinsrerunnouvellmentdansunconteneurclefsuniques.Cettemthode
renvoieunepairecontenantlitrateurrfrenantcetlmentdansleconteneuretunboolen
377
Chapitre17.Lesconteneurs
indiquantsilinsertionaeffectivementeulieu.Cettemthodenestdfiniequepourlesconte
neursassociatifsclefsuniques(cestdirelesmapetlesset).Siaucunlmentduconteneur
necorrespondlaclefdellmentpassenparamtre,cetlmentestinsrdansleconteneur
true.Enrevanche,siunautre
etlavaleurrenvoyedansledeuximechampdelapairevaut
lmentutilisantcetteclefexistedjdansleconteneur,aucuneinsertionnalieuetledeuxime
champdelapairerenvoyevautalors false.Danstouslescas,litrateurstockdanslepre
mierchampdelavaleurderetourrfrencellmentinsroutrouvdansleconteneur.
La
complexitdecettemthodeestlogarithmique.
iteratorinsert(constvalue_type&valeur)
Insreunnouvellmentdansunconteneurclefsmultiples. Cetteinsertionseproduitquil
yaitdjounonunautrelmentutilisantlammeclefdansleconteneur.
Lavaleurretour
neestunitrateurrfrenantlenouvellmentinsr.Vousnetrouverezcettemthodeque
surlesconteneursassociatifsclefsmultiples,cestadiresurlesmultimapetlesmultiset.La
complexitdecettemthodeestlogarithmique.
Commepourlessquences,lasuppressiondeslmentsdesconteneursassociatifssefaitlaidedes
surchargesdelamthodeerase.Lesdiffrentesversionsdecettemthodesontindiquescidessous:
voiderase(iteratori)
Supprimetousleslmentsdontlaclefestgalelavaleurpasseenparamtre.Cetteopration
apourcomplexit ln(N)+n,o N estlenombredlmentsduconteneuravantsuppressionet
n estlenombredlmentsquiserontsupprims.Cettefonctionretournelenombredlments
effectivement supprims. Cenombrepeut trenul si aucunlment necorrespondlaclef
fournieenparamtre,ouvaloir1pourlesconteneursclefsuniques,outresuprieur1pour
lesconteneursclefsmultiples.
Lesconteneursassociatifsdisposentgalement, toutcommelessquences, dunemthode clear
permettantdevidercompltementunconteneur.Cetteoprationestraliseavecuncotproportion
nelaunombredlmentssetrouvantdansleconteneur.
Exemple1710.Insertionetsuppressiondlmentsduneassociation
#include <iostream>
#include <map>
usingnamespacestd;
typedefmap<int,char* > Int2String;
voidprint(Int2String&m)
378
Chapitre17.Lesconteneurs
{
Int2String::iteratori=m.begin();
while(i!=m.end())
{
cout << i>second << endl;
++i;
}
return;
}
intmain(void)
{
//ConstruituneassociationEntier > Chane:
Int2Stringm;
//Ajoutequelqueslments:
m.insert(Int2String::value_type(2,"Deux"));
pair<Int2String::iterator,bool> res=
m.insert(Int2String::value_type(3,"Trois"));
//Onpeutaussispcifierunindicesur
//lemplacementolinsertionauralieu:
m.insert(res.first,
Int2String::value_type(5,"Cinq"));
//Affichelecontenudelassociation:
print(m);
//Supprimellmentdeclef2:
m.erase(2);
//Supprimellment"Trois"parsonitrateur:
m.erase(res.first);
print(m);
return0;
}
17.3.4.Fonctionsderecherche
Lesfonctionsderecherchedesconteneursassociatifssontpuissantesetnombreuses.Cesmthodes
sontdcritescidessous:
iteratorfind(key_typeclef)
Renvoieunitrateurrfrenantunlmentduconteneurdontlaclefestgalelavaleurpasse
enparamtre.Danslecasdesconteneursclefsmultiples,litrateurrenvoyrfrenceundes
lmentsdontlaclefestgalelavaleurpasseenparamtre.Attention,cenestpasforcment
lepremierlmentduconteneurvrifiantcetteproprit.Siaucunlmentnecorrespondla
clef,litrateurdefinduconteneurestrenvoy.
iteratorlower_bound(key_typeclef)
Renvoieunitrateursurlepremierlmentduconteneurdontlaclefestgalelavaleurpasse
enparamtre.Lesvaleurssuivantesdelitrateurrfrencerontleslmentssuivantsdontlaclef
estsuprieureougalelaclefdecetlment.
379
Chapitre17.Lesconteneurs
iteratorupper_bound(key_typeclef)
Renvoieunitrateursurllmentsuivantledernierlmentdontlaclefestgalelavaleur
passeenparamtre.Silnyapasdetellment,cestdiresiledernierlmentduconteneur
utilisecettevaleurdeclef,renvoielitrateurdefinduconteneur.
pair<iterator,iterator> equal_range(key_typeclef)
Renvoieunepaireditrateursgauxrespectivementauxitrateursrenvoysparlesmthodes
lower_bound et upper_bound. Cettepaireditrateursrfrencedonctousleslmentsdu
conteneurdontlaclefestgalelavaleurpasseenparamtre.
Exemple1711.Recherchedansuneassociation
#include <iostream>
#include <map>
usingnamespacestd;
intmain(void)
{
//Dclareunemapclefsmultiples:
typedefmultimap<int,char* > Int2String;
Int2Stringm;
//Remplitlamap:
m.insert(Int2String::value_type(2,"Deux"));
m.insert(Int2String::value_type(3,"Drei"));
m.insert(Int2String::value_type(1,"Un"));
m.insert(Int2String::value_type(3,"Three"));
m.insert(Int2String::value_type(4,"Quatre"));
m.insert(Int2String::value_type(3,"Trois"));
//Rechercheunlmentdeclef4etlaffiche:
Int2String::iteratori=m.find(4);
cout << i>first << ":"
<< i>second << endl;
//Recherchelepremierlmentdeclef3:
i=m.lower_bound(3);
//Affichetousleslmentsdontlaclefvaut3:
while(i!=m.upper_bound(3))
{
cout << i>first << ":"
<< i>second << endl;
++i;
}
//Effectuelammeopration,maisdemanireplusefficace
//(upper_boundnestpasappelechaqueitration):
pair<Int2String::iterator,Int2String::iterator> p=
m.equal_range(3);
for(i=p.first;i!=p.second;++i)
{
cout << i>first << ":"
<< i>second << endl;
}
return0;
}
Note:Ilexistegalementdessurcharges const pourcesquatremthodesderechercheafinde
pouvoirlesutilisersurdesconteneursconstants.Cesmthodesretournentdesvaleursdetype
380
Chapitre17.Lesconteneurs
const_iteratoraulieudesitrateursclassiques,carilestinterditdemodifierlesvaleursstockes
dansunconteneurdetype const.
Laclasse template mapfournit galement unesurchargepourloprateurdaccsauxmem
bresdetableau [].Cetoprateurrenvoielavaleurdellmentrfrencparsaclefetpermet
dobtenirdirectementcettevaleursanspasserparlamthode find etundrfrencementde
litrateurainsi obtenu.Cetoprateurinsreautomatiquementunnouvellmentconstruitavec
lavaleurpardfautdutypedeslmentsstocksdanslamapsi
aucunlmentnecorrespond
lacleffournieenparamtre.Contrairementloprateur [] desclassesvectoretdeque,cet
oprateurnerenvoiedoncjamaislexceptionout_of_range.
Lesrecherchesdanslesconteneursassociatifssappuientsurlefaitquelesobjetsdisposentdune
relationdordreinduiteparlefoncteurlessappliqusurletypedesdonnesquilsmanipulent.Ce
comportementestgnralementceluiquiestsouhait, maisilexistedessituationsocefoncteur
neconvientpas.Parexemple,onpeutdsirerqueleclassementdesobjetssefassesurunedeleur
donnemembreseulement, ouquelafonctiondecomparaisonutilisepourclasserlesobjetssoit
diffrentedecelleinduiteparlefoncteurless.Labibliothquestandardfournitdonclapossibilitde
spcifierunfoncteurdecomparaisonpourchaqueconteneurassociatif,entantqueparamtretemplate
complmentaireautypededonnesdesobjetscontenus.Cefoncteurdoit,silestspcifi,treprcis
avantletypedelallocateurmmoireutiliser.Ilpourratreconstruitpartirdesfacilitsfournies
parlabibliothquestandardpourlacrationetlamanipulationdesfoncteurs.
Exemple1712.Utilisationdunfoncteurdecomparaisonpersonnalis
#include
#include
#include
#include
#include
<iostream>
<map>
<string>
<functional>
<cstring>
usingnamespacestd;
//Fonctiondecomparaisondechanesdecaractres
//nonsensiblelacassedeslettres:
boolstringless_nocase(conststring&s1,conststring&s2)
{
return(strcasecmp(s1.c_str(),s2.c_str()) < 0);
}
intmain(void)
{
//Dfinitletypedesassociationschanes > entiers
//dontlaclefestindexesanstenircompte
//delacassedeslettres:
typedefmap<string,int,
pointer_to_binary_function
<conststring&,
conststring&,bool>> String2Int;
String2Intm(ptr_fun(stringless_nocase));
//Insrequelqueslmentsdanslamap:
m.insert(String2Int::value_type("a.Un",1));
m.insert(String2Int::value_type("B.Deux",2));
m.insert(String2Int::value_type("c.Trois",3));
//Affichelecontenudelamap:
String2Int::iteratori=m.begin();
while(i!=m.end())
381
Chapitre17.Lesconteneurs
{
cout << i>first << ":"
++i;
}
return0;
}
<iostream>
<string>
<map>
<functional>
<cstring>
usingnamespacestd;
//Classedecomparaisondechanesdecaractres:
classStringLessNoCase:publicbinary_function <string,string,bool>
{
public:
booloperator()(conststring&s1,conststring&s2)
{
return(strcasecmp(s1.c_str(),s2.c_str()) < 0);
}
};
intmain(void)
{
//Dfinitiondutypedesassociationschanes
> entiers
//enspcifiantdirectementletypedefoncteurutiliser
//pourlescomparaisonsdeclefs:
typedefmap<string,int,StringLessNoCase
> String2Int;
//Instanciationduneassociationenutilisant
//lavaleurpardfautdufoncteurdecomparaison:
String2Intm;
//Utilisationdelamap:
m.insert(String2Int::value_type("a.Un",1));
m.insert(String2Int::value_type("B.Deux",2));
382
Chapitre17.Lesconteneurs
m.insert(String2Int::value_type("c.Trois",3));
String2Int::iteratori=m.begin();
while(i!=m.end())
{
cout << i>first << ":"
<< i>second << endl;
++i;
}
return0;
}
Note:Lesdeuxexemplesprcdentsutilisentlafonctionstrcasecmp delabibliothqueCstan
dardpoureffectuerdescomparaisonsdechanesqui netiennentpascomptedelacassedes
caractres.Cettefonctionsutilisecommelafonction strcmp,qui comparedeuxchanesetren
voieunentierdontlesigneindiquesi lapremirechaneestpluspetiteouplusgrandequela
deuxime.Cesfonctionsrenvoient0silesdeuxchanessontstrictementgales.Sivousdsirez
ensavoirplussurlesfonctionsdemanipulationdechanesdelabibliothqueC,veuillezvous
rfrerlabibliographie.
383
Chapitre17.Lesconteneurs
384
Chapitre18.Lesalgorithmes
Laplupartdesoprationsquipeuventtreappliquesauxstructuresdedonnesnesontpasspci
fiquescesstructures. Parexemple, ilestpossibledetrierquasimenttouteslessquences, quece
soientdeslistes,desvecteursoudesdeques.Lesclassestemplate desconteneursdelabibliothque
standardnefournissentdoncquedesmthodesdebasepermettantdelesmanipuler,etraressontles
conteneursquidfinissentdesoprationsdontlerledpasselesimplecadredelajout,delasup
pressionoudelarecherchedlments.Aulieudecela,labibliothquestandarddfinittoutunjeude
fonctions template extrieuresauxconteneursetdontlebutestderalisercesoprationsdehaut
niveau.Cesfonctionssontappelesalgorithmesenraisondufaitquelleseffectuentlestraitements
desalgorithmeslesplusconnusetlesplusutilisseninformatique.
LesalgorithmesnedrogentpaslargledegnricitquelabibliothquestandardC++simpose.
Autrementdit,ilssontcapablesdetravaillerenfaisantlemoinsdhypothsespossiblessurlastructure
dedonnescontenant lesobjetssurlesquelsilssappliquent. Ainsi, touslesalgorithmessont des
fonctions template etilstravaillentsurlesobjetsexclusivementparlintermdiaireditrateurset
defoncteurs.Celasignifiequelesalgorithmespeuvent,enpratique,treutilisssurnimportequelle
structurededonnesounimportequel conteneur, pourvuquelesprconditionsimposessurles
itrateursetletypedesdonnesmanipulessoientrespectes.
Commepourlesmthodespermettantdemanipulerlesconteneurs,lesalgorithmessontdcritspar
leursmantiqueetparleurcomplexit.Celasignifiequelesimplmentationsdelabibliothquestan
dardsontlibresquantlamanirederalisercesalgorithmes,maisquellesdoiventimprativement
respecterlescontraintesdeperformancesimposesparlanormedelabibliothquestandard.Enpra
tiquecependant,toutcommepourlesstructuresdedonnesdesconteneurs,cescontraintesimposent
souventlalgorithmesousjacentpourlimplmentationdecesfonctionnalitsetlalgorithmeutilis
estlemeilleuralgorithmeconnucejour.Autrementdit,lesalgorithmesdelabibliothquestandard
sontforcmentlesplusefficacesquisoient.
Laplupartdesalgorithmesdelabibliothquestandardsontdclarsdanslentte algorithm.Cer
tainsalgorithmesontttoutefoisdfinisinitialementpourlesvalarrayetnapparaissentdoncpas
danscetentte.Aulieudecela,ilssontdclarsdanslentte numeric.Cesalgorithmessontpeu
nombreuxetcetteparticularitserasignaledansleurdescription.
Lenombredesalgorithmesdfinisparlabibliothquestandardest
impressionnant et couvresans
doutetouslesbesoinscourantsdesprogrammeurs.Ilestdoncdifficile,enraisondecettegrandediver
sit,deprsenterlesalgorithmesdemanirestructure.Cependant,lessectionssuivantesregroupent
cesalgorithmesenfonctiondelanaturedesoprationsquilssontsupposseffectuer.Cesoprations
comprennentlesoprationsdemanipulationgnralesdesdonnes,lesrecherchesdlmentsselon
descritresparticuliers,lesoprationsdetrietdecomparaison,etenfinlesoprationsdemanipulation
ensemblistes.
18.1.Oprationsgnralesdemanipulationdes
donnes
Lesalgorithmesgnrauxdemanipulationdesdonnespermettentderalisertouteslesoprations
classiquesdetypecration,copie,suppressionetremplacement,maisgalementdemodifierlordre
dessquencesdlmentsainsiquedappliqueruntraitementsurchacundeslmentsdesconteneurs.
Certainsalgorithmespeuventmodifiersoitlesdonnescontenuesparlesconteneurssurlesquelsils
travaillent, soitlesconteneurseuxmmes. Engnralcesalgorithmestravaillentsurplace, cest
direquilsmodifientlesdonnesduconteneurdirectement.Cependant,pourcertainsalgorithmes,il
385
Chapitre18.Lesalgorithmes
estpossibledestockerlesdonnesmodifiesdansunautreconteneur.Leconteneursourcenestdonc
pasmodifietlesdonnes,modifiesounon,sontcopiesdansleconteneurdestination.Engnral,
lesversionsdesalgorithmescapablesdefairecettecopielavolenesontfourniesquepourles
algorithmespeucomplexescarlecotdelacopiepeutdanscecastreaussigrandouplusgrandque
lecotdutraitementdesalgorithmeseuxmmes.Ilestdoncjustifipourcesalgorithmesdedonnerla
possibilitderaliserlacopiependantleurtraitementafindepermettreauxprogrammesdoptimiser
lesprogrammesselonlescasdutilisation.Lenomdesalgorithmesquiralisentunecopielavole
estlemmenomqueleuralgorithmedebase,maissuffixparlemot _copy .
18.1.1.Oprationsdinitialisationetderemplissage
Ilexistedeuxmthodespermettantdinitialiserunconteneuroudegnrerunesriedobjetspour
initialiserunconteneur.Lapremiremthodenepermetquedegnrerplusieurscopiesdunmme
objet,quelonspcifieparvaleur,alorsqueladeuximepermetdappelerunefonctiondegnration
pourchaqueobjetcrer.
Lesalgorithmesdegnrationetdinitialisationsontdclarsdelamaniresuivantedanslentte
algorithm :
template <classForwarIterator,classT>
voidfill(ForwardIteratorpremier,ForwardIteratordernier,constT&valeur);
template <classOutputIterator,classT>
voidfill_n(OutputIteratorpremier,Sizenombre,constT&valeur);
tempalte <classForwardIterator,classT,classGenerator>
voidgenerate(ForwardIteratorpremier,ForwardIteratordernier,Generatorg);
template <classOutputIterator,classT,classGenerator
>
voidgenerate_n(OutputIteratorpremier,Sizenombre,Generatorg);
<iostream>
<list>
<iterator>
<algorithm>
usingnamespacestd;
intcompte()
{
staticinti=0;
returni++;
}
386
Chapitre18.Lesalgorithmes
intmain(void)
{
//Creunelistede20entiersconscutifs:
typedeflist<int> li;
lil;
generate_n(back_inserter(l),20,compte);
//Affichelaliste:
li::iteratori=l.begin();
while(i!=l.end())
{
cout << *i << endl;
++i;
}
return0;
}
Cesalgorithmeseffectuentexactementautantdaffectationsquilyadlmentscrerouinitiali
ser.Leurcomplexitestdonclinaireenfonctiondunombredeceslments.
18.1.2.Oprationsdecopie
Labibliothquestandarddfinitdeuxalgorithmesfondamentauxpourraliserlacopiedesdonnes
desconteneurs.Cesalgorithmessontdclarscommesuitdanslentte algorithm :
template <classInputIterator,classOutputIterator
>
OutputIteratorcopy(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination);
template <classBidirectionalIterator1,classBidirectionalIterator2
>
BidirectionalIterator2copy_backward(
BidirectionalIterator1premier,BidirectionalIterator1dernier,
BidirectionalIterator2fin_destination);
387
Chapitre18.Lesalgorithmes
char*pFin=sBuffer+strlen(sBuffer);
//craselachaneparellemmepartirdud:
copy_backward(sBuffer,pFin3,pFin);
//Affichelersultat:
cout << sBuffer << endl;
return0;
}
Note:Lafonction strlen utilisedanscet exempleest unedesfonctionsdelabibliothque
Cstandard,qui estdclaredanslentte cstring.Ellepermetdecalculerlalongueurdune
chanedecaractresC(sanscompterlecaratrenulterminal).
Cesalgorithmeseffectuentexactementautantdaffectationquilyadlmentscopier.Leurcom
plexitestdonclinaireenfonctiondunombredeceslments.
Note:Il existegalementdesalgorithmescapablesderaliserunecopiedeleurrsultatla
vole.Lenomdecesalgorithmesestgnralementlenomdeleuralgorithmedebasesuffix
parlachane _copy.Cesalgorithmesserontdcritsavecleursalgorithmesdebase.
18.1.3.Oprationsdchangedlments
Ilestpossibledchangerlecontenudedeuxsquencesdlmentsgrceunalgorithmeddicette
tche,lalgorithme swap_ranges.Cetalgorithmeestdclarcommesuitdanslenttealgorithm :
template <classForwardIterator,classForwardIterator2>
ForwardIterator2swap_ranges(ForwardIteratorpremier,ForwardIteratordernier,
ForwardIterator2destination);
Cetalgorithmeprendenparamtrelesdeuxitrateursdfinissantlapremiresquenceetunitrateur
destinationpermettantdindiquerlepremierlmentdeladeuximesquenceavecleslmentsde
laquellelchangedoittrefait.Lavaleurretourneestlitrateurdefindecettesquence,unefois
loprationtermine.
Exemple183.Algorithmedchange
#include <iostream>
#include <list>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
//Dfinitunelistedentiers:
typedeflist<int> li;
lil;
l.push_back(2);
l.push_back(5);
l.push_back(3);
388
Chapitre18.Lesalgorithmes
l.push_back(7);
//Dfinituntableaudequatrelments:
intt[4]={10,11,12,13};
//changelecontenudutableauetdelaliste:
swap_ranges(t,t+4,l.begin());
//Afficheletableau:
inti;
for(i=0;i <4;++i)
cout << t[i] << "";
cout << endl;
//Affichelaliste:
li::iteratorit=l.begin();
while(it!=l.end())
{
cout << *it << "";
++it;
}
cout << endl;
return0;
}
Cet algorithmenchangepasplusdlmentsquencessaire,
linaireenfonctiondelatailledelasquenceinitiale.
18.1.4.Oprationsdesuppressiondlments
Les conteneurs delabibliothquestandarddisposent
tous demthodes puissantes permettant
deffectuerdessuppressionsdlmentsselondiffrentscritres.Toutefois,labibliothquestandard
dfinit galement des algorithmes desuppressiondlments dans des squences. Enfait, ces
algorithmesneffectuentpasproprementparlerdesuppression,maisunercrituredessquences
aucours delaquelleles lments supprimer sont tout simplement ignors. Ces algorithmes
renvoientdonclitrateurdudernierlmentcopi,audelduquellasquenceinitialeestinchange.
Labibliothquestandardfournitgalementdesversionsdecesalgorithmescapablesderaliserune
copielavoledeslmentsdelasquencersultat. Cesalgorithmespeuvent donctypiquement
treutilisspoureffectuerunfiltresurdeslmentsdont lebut serait desupprimerleslments
indsirables.
Lesfonctionsdesuppressiondeslmentssontdclarescommesuitdanslentte algorithm :
template <classForwardIterator,classT>
ForwardIteratorremove(ForwardIteratorpremier,ForwardIteratorsecond,
constT&valeur);
template <classInputIterator,classOutputIterator,classT>
OutputIteratorremove_copy(InputIteratorpremier,InputIteratorsecond,
OutputIteratordestination,constT&valeur);
template <classForwardIterator,classPredicate>
ForwardIteratorremove_if(ForwardIteratorpremier,ForwardIteratorsecond,
Predicatep);
template <classInputIterator,classOutputIterator,classPredicate
>
OutputIteratorremove_copy_if(InputIteratorpremier,InputIteratorsecond,
OutputIteratordestination,Predicatep);
389
Chapitre18.Lesalgorithmes
Demaniresimilaire,labibliothquestandarddfinitgalementdesalgorithmespermettantdesup
primerlesdoublonsdansdessquencesdlments.Cesalgorithmessontdclarscommesuitdans
lentte algorithm :
template<classForwardIterator>
ForwardIteratorunique(ForwardIteratorpremier,ForwardIteratordernier);
template<classForwardIterator,classOutputIterator>
OutputIteratorunique_copy(ForwardIteratorpremier,ForwardIteratordernier);
template <classForwardIterator,classBinaryPredicate>
ForwardIteratorunique(ForwardIteratorpremier,ForwardIteratordernier,
390
Chapitre18.Lesalgorithmes
BinaryPredicatep);
template <classForwardIterator,classOutputIterator,classBinaryPredicate>
OutputIteratorunique_copy(ForwardIteratorpremier,ForwardIteratordernier,
BinaryPredicatep);
Exemple185.Algorithmedesuppressiondesdoublons
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
//Construituntableaude10entiers:
intt[10]={1,2,2,3,5,2,4,3,6,7};
//Supprimelesdoublons:
int*fin=unique(t,t+10);
//Afficheletableaursultat:
int*p=t;
while(p!=fin)
{
cout << *p << endl;
++p;
}
return0;
}
Letestdesuppressionestappliquparcesalgorithmesautantdefoisquilyadlmentsdansla
squenceinitiale,cestdirequeleurcomplexitestlinaireenfonctiondunombredlmentsde
cettesquence.
18.1.5.Oprationsderemplacement
Lesalgorithmesderemplacementpermettentderemplacertousleslmentsdunconteneurvrifiant
unepropritparticulireparunautrelment dont lavaleurdoit trefournieenparamtre. Les
lmentsdevanttreremplacspeuventtreidentifissoitparleurvaleur,soitparunprdicatunaire
prenantenparamtreunlmentetrenvoyantunboolenindiquantsicetlmentdoittreremplac
ounon.Lesalgorithmesderemplacementsontdclarscommesuitdanslentte algorithm :
template <classForwardIterator,classT >
391
Chapitre18.Lesalgorithmes
voidreplace(ForwardIteratorpremier,ForwardIteratordernier,
constT&ancienne_valeur,constT&nouvelle_valeur);
template <classInputIterator,classOutputIterator,classT>
voidreplace_copy(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination,
constT&ancienne_valeur,constT&nouvelle_valeur);
template <classForwardIterator,classPredicate,classT >
voidreplace_if(ForwardIteratorpremier,ForwardIteratordernier,
Predicatep,constT&nouvelle_valeur);
template <classInputIterator,classOutputIterator,
classPredicate,classT >
voidreplace_copy_if(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination,
Predicatep,constT&nouvelle_valeur);
Lesalgorithmesderemplacementpeuventtravaillersurplaceoueffectuerunecopielavoledes
lmentssurlesquelsilstravaillent.Lesversionscapablesderalisercescopiessontidentifiespar
lesuffixe _copy deleurnom.Cesalgorithmesprennentunparamtresupplmentairepermettantde
spcifierlemplacementdestinationoleslmentscopisdevronttrestocks.Ceparamtreestun
itrateur,toutcommelesparamtresquiindiquentlintervalledlmentsdanslequellarechercheet
leremplacementdoiventtreraliss.
Exemple186.Algorithmederechercheetderemplacement
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={1,2,5,3,2,7,6,4,2,1};
//Remplacetousles2pardes9:
replace(t,t+10,2,9);
//Affichelersultat:
inti;
for(i=0;i <10;++i)
cout << t[i] << endl;
return0;
}
Letestderemplacementestappliquparcesalgorithmesautantdefoisquilyadeslmentsdansla
squenceinitiale,cestdirequeleurcomplexitestlinaireenfonctiondunombredlmentsde
cettesquence.
18.1.6.Rorganisationdesquences
CommeillatexpliqudanslaSection17.2,lordredeslmentsdunesquenceestimportant.
Laplupartdessquencesconserventleslmentsdanslordredanslequelilsonttinsrs,dautre
serorganisentautomatiquementlorsquelontravailledessuspourassurerunordrebiendfini.
392
Chapitre18.Lesalgorithmes
Labibliothquestandardfournitplusieursalgorithmespermettantderorganiserlasquencedesl
mentsdansunconteneurquineprendpasenchargeluimmelordredeseslments.
Cesalgo
rithmespermettentderaliserdesrotationsetdespermutationsdeslments,
dessymtriesetdes
inversions,ainsiquedelesmlangerdemanirealatoire.
Note:Il existegalementdesalgorithmesdetri extrmementefficaces,maiscesalgorithmes
serontdcritsplusloindansunesectionquileurestconsacre.
18.1.6.1.Oprationsderotationetdepermutation
Lesalgorithmesderotationpermettentdefairetournerlesdiffrentslmentsdunesquencedansun
sensoudanslautre.Parexemple,dansunerotationverslagaucheduneplace,ledeuximelment
peutprendrelaplacedupremier,letroisimecelledudeuxime,etc.,lepremierlmentrevenant
laplacedudernier.Cesalgorithmessontdclarsdelamaniresuivantedanslenttealgorithm :
template <classForwardIterator>
voidrotate(ForwardIteratorpremier,ForwardIteratorpivot,
ForwardIteratordernier);
template <classForwardIterator,classOutputIterator>
voidrotate_copy(ForwardIteratorpremier,ForwardIteratorpivot,
ForwardIteratordernier,OutputIteratordestination);
Lesalgorithmesderotationprennentenparamtreunitrateurindiquantlepremierlmentdelas
quencedevantsubirlarotation,unitrateurrfrenantllmentquisetrouveraenpremireposition
aprslarotation,etunitrateurrfrenantllmentsuivantledernierlmentdelasquence.Ainsi,
poureffectuerunerotationdunepositionverslagauche,ilsuffitdutiliserpourlitrateur pivot la
valeurdelitrateursuivantlitrateur premier et,poureffectuerunerotationdunepositionversla
droite,ilfautprendrepourlitrateur pivot lavaleurprcdantcelledelitrateur dernier.
Exemple187.Algorithmederotation
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={0,1,2,3,4,5,6,7,8,9};
//Effectueunerotationpouramenerlequatrime
//lmentenpremireposition:
rotate(t,t+3,t+10);
//Affichelersultat:
inti;
for(i=0;i <10;++i)
cout << t[i] << endl;
return0;
}
Labibliothquefournitgalementdesalgorithmespermettantdobtenirlensembledespermutations
dunesquencedlments.Rappelonsquunepermutationestunedescombinaisonspossiblesdes
393
Chapitre18.Lesalgorithmes
valeursdesdiffrentslmentsdunensemble, enconsidrantleslmentsdgalevaleurcomme
identiques.Parexemple,siunensemblecontientdeuxlmentsdemmevaleur,ilnyaquuneseule
permutationpossible:lesdeuxvaleurs.Sienrevanchecesdeuxlmentsontdeuxvaleursdistinctes,
onpeutraliserdeuxpermutationsselonlavaleurquelonplaceenpremier.
Lesalgorithmesdepermutationdelabibliothquenepermettentpasdobtenirlespermutationsdi
rectement.Aulieudecela,ilspermettentdepasserdunepermutationlapermutationsuivanteou
laprcdente.Celasupposequunerelationdordresoitdfiniesurlensembledespermutationsde
lasquence.Labibliothquestandardutiliselordrelexicographiquepourclassercespermutations.
Autrementdit,lespremirespermutationssontcellespourlesquelleslespremierslmentsontles
valeurslesplusfaibles.
Lesalgorithmesdecalcul despermutationssuivanteet prcdentesont dclarscommesuit dans
lentte algorithm :
template <classBidirectionalIterator
>
boolnext_permutation(BidirectionalIteratorpremier,BidirectionalIteratordernier);
template <classBidirectionalIterator
>
boolprev_permutation(BidirectionalIteratorpremier,BidirectionalIteratordernier);
Cesalgorithmesprennenttouslesdeuxdeuxitrateursindiquantleslmentsdevantsubirlapermu
tationetrenvoientunboolenindiquantsilapermutationsuivanteouprcdenteexisteounon.Sices
permutationsnexistentpas,lesalgorithmes next_permutation et prev_permutation bouclent
etcalculentrespectivementlapluspetiteetlaplusgrandepermutationdelensembledespermuta
tions.
Exemple188.Algorithmedepermutation
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[3]={1,1,2};
//Affichelensembledespermutationsde(1,1,2):
do
{
inti;
for(i=0;i <3;++i)
cout << t[i] << "";
cout << endl;
}
while(next_permutation(t,t+3));
return0;
}
Lesalgorithmesderotationeffectuentautantdchangequilyadlmentsdanslasquenceinitiale,
etlesalgorithmesdecalculdepermutationenfontexactementlamoiti.Lacomplexitdecesalgo
rithmesestdonclinaireenfonctiondunombredlmentsdelintervallequidoitsubirlopration.
394
Chapitre18.Lesalgorithmes
18.1.6.2.Oprationsdinversion
reverse et
Ilestpossibledinverserlordredeslmentsdunesquencelaidedesalgorithmes
reverse_copy.Cesalgorithmessontdclarsdelamaniresuivantedanslentte algorithm :
template <classBidirectionalIterator
>
voidreverse(BidirectionalIteratorpremier,BidirectionalIteratordernier);
template <classBidirectionalIterator,classOutputIterator
>
OutputIteratorreverse_copy(BidirectionalIteratorpremier,
BidirectionalIteratordernier,OutputIteratordestination);
Cesalgorithmesprennentenparamtrelesitrateurspermettantdespcifierlintervalledeslments
quidoittreinvers.Laversiondecetalgorithmequipermetderaliserunecopieprendunparamtre
supplmentairequidoitrecevoirlitrateurrfrenantlemplacementdestinationdanslequeller
sultatdelinversiondoittrestock.Cetitrateurretournelavaleurdelitrateurdestinationpassle
dernierlmentcrit.
Exemple189.Algorithmedinversion
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={0,1,2,3,4,5,6,7,8,9};
//Inverseletableau:
reverse(t,t+10);
//Affichelersultat:
inti;
for(i=0;i <10;++i)
cout << t[i] << endl;
return0;
}
18.1.6.3.Oprationsdemlange
Il est possiblederedistribueralatoirement leslmentsdunesquencelaidedelalgorithme
random_shuffle.Cetalgorithmeestfournisouslaformededeuxsurchargesdclarescommesuit
danslentte algorithm :
template <classRandomAccessIterator
>
voidrandom_shuffle(RandomAccessIteratorpremier,RandomAccessIteratordernier);
template <classRandomAccessIterator,classRandomNumberGenerator
>
voidrandom_shuffle(RandomAccessIteratorpremier,RandomAccessIteratordernier,
RandomNumberGeneratorg);
395
Chapitre18.Lesalgorithmes
Cesalgorithmesprennentenparamtrelesitrateursdedbutetdefindelasquencedontlesl
mentsdoiventtremlangs.Ladeuximeversiondecetalgorithmepeutprendreendernierpara
mtreunfoncteurquiserautilispourcalculerlespositionsdeslmentspendantlemlange.Ainsi,
cettesurchargepermetdespcifiersoimmelafonctiondedistributionutiliserpoureffectuercette
nouvellerpartition. Cefoncteurdoitprendreenparamtreunevaleurdutypedifference_typedes
itrateursutilisspourrfrencerleslmentsdelasquence,etrenvoyerunevaleurcompriseentre0
etlavaleurreueenparamtre.Ildoitdoncsecomportercommelafonction rand delabibliothque
standardC(dclaredanslefichierdentte cstdlib).
Exemple1810.Algorithmedemlange
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={0,1,2,3,4,5,6,7,8,9};
//Mlangeletableaut:
random_shuffle(t,t+10);
//Affichelersultat:
inti;
for(i=0;i <10;++i)
cout << t[i] << endl;
return0;
}
Cesalgorithmeseffectuentexactementlenombredlmentsdelasquencemlangermoinsun
changesdevaleurs. Leurcomplexitest donclinaireenfonctiondunombredlmentsdeces
squences.
18.1.7.Algorithmesditrationetdetransformation
Lesalgorithmesdetransformationetditrationdelabibliothquestandardfontpartiedesplusutiles
puisquilspermettentdeffectueruntraitementsurlensembledeslmentsdunconteneur.Cestrai
tementspeuventmodifierounonceslmentsoutoutsimplementcalculerunevaleurpartirdeces
lments.
Lesdeuxprincipauxalgorithmesfournisparlabibliothquestandardsontsansdoutelesalgorithmes
for_each et transform,quipermettentdeffectueruneactionsurchaquelmentdunconteneur.
Cesalgorithmessontdclarscommesuitdanslentte algorithm :
template <classInputIterator,classFunction
>
Functionfor_each(InputIteratorpremier,InputIteratordernier,Functionf);
template <classInputIterator,classOutputIterator,
classUnaryOperation>
OutputIteratortransform(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination,UnaryOperationop);
template <classInputIterator1,classInputIterator2,
classOutputIterator,classBinaryOperation >
OutputIteratortransform(InputIterator1premier1,InputIterator1dernier1,
396
Chapitre18.Lesalgorithmes
InputIterator2premier2,OutputIteratordestination,
BinaryOperationop);
Commevouspouvezleconstaterdaprscetexemple, ilesttoutfaitpossibledutiliserlamme
valeur pour litrateur premier et litrateur destination. Celasignifiequeleslmentsit
rspeuventtreremplacsparlesnouvellesvaleurscalculesparlefoncteurfournilalgorithme
transform.
Uncasparticulierdesalgorithmesditrationestceluidesalgorithmes count et count_if puisque
letraitementeffectuestalorssimplementledcomptedeslmentsvrifiantunecertainecondition.
Cesdeuxalgorithmespermettenteneffetdecompterlenombredlmentsdunconteneurdontla
397
Chapitre18.Lesalgorithmes
valeurestgaleunevaleurdonneouvrifiantuncritrespcifiparlintermdiairedunprdicat
unaire.Cesdeuxalgorithmessontdclarsdelamaniresuivantedanslenttealgorithm :
template <classInputIterator,classT>
iterator_traits<InputIterator>::difference_type
count(InputIteratorpremier,InputIteratordernier,constT&valeur);
template <classInputIterator,classPredicate
>
iterator_traits<InputIterator>::difference_type
count_if(InputIteratorpremier,InputIteratordernier,Predicatep);
Commevouspouvezleconstater, cesalgorithmesprennentenparamtredeuxitrateursspcifiant
lintervalledeslmentssurlesquelsletestdoittreeffectu,etlavaleuraveclaquelleceslments
doiventtrecomparsouunprdicatunaire.Danscecas,lersultatdeceprdicatindiquesillment
quilreoitenparamtredoittrecomptounon.
Exemple1812.Algorithmededcomptedlments
#include <iostream>
#include <functional>
#include <algorithm>
usingnamespacestd;
boolparity_even(inti)
{
return(i&1)==0;
}
intmain(void)
{
intt[10]={0,1,2,3,4,5,6,7,8,9};
//Comptelenombredlmentspairs:
cout << count_if(t,t+10,ptr_fun(&parity_even))<< endl;
return0;
}
Touslesalgorithmesditrationnefontquunseulpassagesurchaquelmentitr.Autrementdit,la
complexitdecesalgorithmesestlinaireenfonctiondunombredlmentscomprisentrelesdeux
itrateursspcifiantlintervalledlmentssurlequelilssontappliqus.
Enfin,labibliothquestandardfournitdesalgorithmesdecalculplusvolus,capablesdetravailler
surleslmentsdesconteneurs.Cesalgorithmessontgnralementutilissencalculnumriqueet
onttconusspcialementpourlestableauxdevaleurs.Cependant,ilsrestenttoutfaitutilisables
surdautresconteneursquelesvalarray,laseuledistinctionquilsontaveclesautresalgorithmesdela
bibliothquestandardestquilssontdclarsdanslentte numeric aulieudelentte algorithm.
Cesalgorithmessontlessuivants:
template <classInputIterator,classT>
Taccumulate(InputIteratorpremier,InputIteratordernier,Tinit);
template <classInputIterator,classT,classBinaryOperation
>
Taccumulate(InputIteratorpremier,InputIteratordernier,
Tinit,BinaryOperationop);
398
Chapitre18.Lesalgorithmes
template <classInputIterator1,classInputIterator2,classT>
Tinner_product(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,Tinit);
template <classInputIterator1,classInputIterator2,classT,
classBinaryOperation1,classBinaryOperation2
>
Tinner_product(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,Tinit,
BinaryOperation1op1,BinaryOperationop2);
template <classInputIterator,classOutputIterator
>
OutputIteratorpartial_sum(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination);
template <classInputIterator,classOutputIterator,classBinaryOperation
>
OutputIteratorpartial_sum(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination,BinaryOperationop);
template <classInputIterator,classOutputIterator
>
OutputIteratoradjacent_difference(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination);
template <classInputIterator,classOutputIterator,classBinaryOperation
>
OutputIteratoradjacent_difference(InputIteratorpremier,InputIteratordernier,
OutputIteratordestination,BinaryOperationop);
Cesalgorithmescorrespondentdesoprationscourantes,quelonfaitgnralementsurlestableaux
denombresdetypevalarray.Lalgorithme accumulate permetgnralementderaliserlasomme
desvaleursquisontstockesdansunconteneur.Lalgorithmeinner_product estutilisquantlui
pourraliserleproduitscalairededeuxsquencesdenombres,oprationmathmatiquegnralement
effectuedanslecalculvectoriel.Enfin,lesalgorithmes partial_sum et adjacent_difference
ralisentrespectivementlecalculdessommespartiellesetdesdiffrencesdeuxdeuxdeslments
dunconteneur.
Pout touscesalgorithmes, il est possibledutiliserdautresoprationsquelesoprationsgnra
lement utilises. Parexemple, accumulate peut utiliseruneautreoprationqueladditionpour
accumulerlesvaleursdeslments. Pourcela, labibliothquestandardfournitdessurcharges
decesalgorithmescapablesdetravailleravecdesfoncteursbinaires. Cesfoncteursdoiventaccep
terdeuxparamtresdutypedeslmentsduconteneursurlequellesalgorithmessontappliquset
renvoyerunevaleurdummetype,calculepartirdecesparamtres.
Lalgorithme accumulate prenddoncenpremiersparamtreslesitrateursdfinissantlintervalle
desvaleursquidoiventtreaccumules. Ilinitialiselavaleurdunevariableaccumulateuravecla
valeurfournieentroisimeparamtre, et parcourslensembledeslments. Pourchaquelment
trait, accumulate remplacelavaleurcourantedelaccumulateurparlersultat
delopration
daccumulationappliquelaccumulateurluimmeetlavaleurdellmentcourant.Pardfaut,
loprationdaccumulationutiliseestladdition,maisilestpossibledechangercecomportementen
fournissantunfoncteurbinaireendernierparamtre.Lorsquelensembledeslmentsatparcouru,
lavaleurdelaccumulateurestretourne.
Exemple1813.Algorithmedaccumulation
#include <list>
#include <numeric>
399
Chapitre18.Lesalgorithmes
#include <functional>
#include <iostream>
usingnamespacestd;
intmain(void)
{
//Construitunelistedentiers:
typedeflist<int> li;
lil;
l.push_back(5);
l.push_back(2);
l.push_back(9);
l.push_back(1);
//Calculeleproduitdecesentiers:
intres=accumulate(l.begin(),l.end(),
1,multiplies<int>());
cout << res << endl;
return0;
}
400
Chapitre18.Lesalgorithmes
possibledespcifieruneautreoprationqueladditionlaidedunfoncteurbinairequelonpassera
endernierparamtre.
Enfin,lalgorithme adjacent_difference estlalgorithmeinversedelalgorithme parial_sum.
Eneffet,ilpermetdecalculerlasriedesdiffrencesdesvaleursdeslmentssuccessifsdunesuite
devaleurs,prisdeuxdeux. Cetalgorithmeprendenparamtrelesitrateursdcrivantlasuitede
valeurssurlaquelleildoittravailler,litrateurdelemplacementdestinationolesrsultatsdevront
trestocksetventuellementlefoncteurappliquerauxcouplesdlmentssuccessifstraitspar
lalgorithme. Lapremirediffrenceestcalculeensupposantquellmentprcdentlepremier
lment apourvaleurlavaleurnulle. Ainsi, lepremierlment delemplacement destinationest
toujoursgalaupremierlmentdelasuitedevaleurssurlaquellelalgorithmetravaille.
Exemple1815.Algorithmesdesommespartiellesetdediffrencesadjacentes
#include <iostream>
#include <numeric>
usingnamespacestd;
intmain(void)
{
intt[4]={1,1,1,1};
//Calculelessommespartiellesdeslments
//dutableau:
partial_sum(t,t+4,t);
//Affichelersultat:
inti;
for(i=0;i <4;++i)
cout << t[i] << "";
cout << endl;
//Calculelesdiffrencesadjacentes:
adjacent_difference(t,t+4,t);
//Cestletableauinitial:
for(i=0;i <4;++i)
cout << t[i] << "";
cout << endl;
return0;
}
Touscesalgorithmestravaillentenuneseulepassesurleslmentsdesconteneurssurlesquelsils
sappliquent.Leurcomplexitestdonclinaireenfonctiondunombredlmentsspcifisparles
itrateursfournisenpremierparamtre.
18.2.Oprationsderecherche
Engnral, laplupartdesoprationsderecherchedemotifsquelesprogrammessontsusceptibles
deffectuersefontsurdeschanesdecaractresousurlesconteneursassociatifs.Cependant,ilpeut
trencessairederechercherunlment dansunconteneurselonuncritreparticulieroudere
chercherunesquencedlmentsconstituantunmotifretrouverdanslasuitedeslmentsdun
conteneur.Enfin,ilestrelativementcourantdavoirrechercherlesgroupesdlmentsconscutifs
disposantdelammevaleurdansunconteneur.Toutescesoprationspeuventtreraliseslaide
desalgorithmesderecherchequelabibliothquestandardmetladispositiondesprogrammeurs.
401
Chapitre18.Lesalgorithmes
18.2.1.Oprationderecherchedlments
Lepremiergroupedoprationsderecherchecontienttouslesalgorithmespermettantderetrouver
unlmentdansunconteneur,enlidentifiantsoitparsavaleur,soitparunepropritparticulire.
Toutefois,cetlmentpeutnepastreleseullmentvrifiantcecritre.Labibliothquestandard
dfinit doncplusieursalgorithmespermettant derechercherceslmentsdediffrentesmanires,
facilitantainsilesoprationsderecherchedansdiffrentscontextes.
Lesalgorithmesderecherchedlmentssont lesalgorithmes find et find_if, qui permettent
deretrouverlepremierlmentdunconteneurvrifiantunepropritparticulire, etlalgorithme
find_first_of,quipermetderetrouverlepremierlmentvrifiantunerelationavecunevaleur
parmiunensembledevaleursdonnes.Touscesalgorithmessontdclarsdanslentte algorithm :
template <classInputIterator,classT>
InputIteratorfind(InputIteratorpremier,InputIteratordernier,constT&valeur);
template <classInputIterator,classPredicate
>
InputIteratorfind_if(InputIteratorpremier,InputIteratordernier,Predicatep);
template <classInputIterator,classForwardIterator
>
InputIteratorfind_first_of(InputIteratorpremier1,InputIteratordernier1,
ForwardIteratorpremier2,ForwardIteratordernier2);
template <classInputIterator,classForwardIterator,classBinaryPredicate
>
InputIteratorfind_first_of(InputIteratorpremier1,InputIteratordernier1,
ForwardIteratorpremier2,ForwardIteratordernier2,
BinaryPredicatep);
402
Chapitre18.Lesalgorithmes
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={0,5,3,4,255,7,0,5,255,9};
//Rechercheleslmentsvalant0ou255:
intsep[2]={0,255};
int*debut=t;
int*fin=t+10;
int*courant;
while((courant=find_first_of(debut,fin,
sep,sep+2))!=fin)
{
//Affichelapositiondellmenttrouv:
cout << *courant << "enposition"
<<
courantt << endl;
debut=courant+1;
}
return0;
}
18.2.2.Oprationsderecherchedemotifs
Lesoprationsderecherchedemotifspermettentdetrouverlespremiresetlesderniresoccurrences
dunmotifdonndansunesuitedevaleurs. Cesoprationssont ralisesrespectivement parles
algorithmes search et find_end,dontladclarationdanslentte algorithm estlasuivante:
template <classForwardIterator1,classForwardIterator2>
ForwardIterator1search(ForwardIterator1premier1,ForwardIterator1dernier1,
ForwardIterator2premier2,ForwardIterator2dernier2);
template <classForwardIterator1,classForwardIterator2,
classBinaryPredicate>
ForwardIterator1search(ForwardIterator1premier1,ForwardIterator1dernier1,
ForwardIterator2premier2,ForwardIterator2dernier2,
BinaryPredicatep);
template <classForwardIterator1,classForwardIterator2>
ForwardIterator1find_end(ForwardIterator1premier1,ForwardIterator1dernier1,
ForwardIterator2premier2,ForwardIterator2dernier2);
template <classForwardIterator1,classForwardIterator2,
classBinaryPredicate>
ForwardIterator1find_end(ForwardIterator1premier1,ForwardIterator1dernier1,
ForwardIterator2premier2,ForwardIterator2dernier2,
BinaryPredicatep);
403
Chapitre18.Lesalgorithmes
dgalitdutypedeslmentscompars.Ladeuximepermetdeffectuercettecomparaisonlaide
dunprdicatbinaire,quelonfournitdanscecasendernierparamtre.
Lavaleurretourneparlalgorithmesearch estunitrateursurlapremireoccurrencedumotifdans
lasquencedevaleursspcifiesparlesitrateurs premier1 et dernier1 oulitrateur dernier1
luimmesicemotifnyapparatpas.Demme,lavaleurretourneparlalgorithme find_end est
unitrateurrfrenantladernireoccurrencedumotifdanslasquencedesvaleursspcifiepar
lesitrateurs premier1 et dernier1,oulitrateur dernier1 luimmesilemotifnapasputre
trouv.
Exemple1817.Algorithmesderecherchedemotif
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={1,2,4,5,3,1,2,3,5,9};
//Recherchelemotif{1,2,3}dansletableau:
intmotif[3]={1,2,3};
int*p=search(t,t+10,motif,motif+3);
cout << "{1,2,3}enposition"
<<
pt << endl;
//Rechercheladernireoccurrencede{1,2}:
p=find_end(t,t+10,motif,motif+2);
cout << "Dernier{1,2}enposition" <<
pt << endl;
return0;
}
Lesdeuxsurchargesdecetalgorithmeprennentenparamtrelesitrateursdfinissantlasquencede
valeursdanslaquellelarecherchedoittreeffectue,lalongueurdumotifrechercher,etlavaleurdes
lmentsdecemotif.Ladeuximeversiondecetalgorithmeacceptegalementunprdicatbinaire,
quiserautilispoureffectuerlacomparaisondeslmentsdelasquencedanslaquellelarecherche
sefaitaveclavaleurpasseenparamtre.Lavaleurretourneestunitrateurrfrenantlapremire
occurrencedumotifrecherchoulitrateur dernier sicemotifnexistepasdanslasquencede
404
Chapitre18.Lesalgorithmes
valeursanalyse.Lacomplexitdelalgorithme search_n est nm,o n estlatailledelasquence
danslaquellelarechercheesteffectueet m estlalongueurdumotifrecherch.
Uncasparticulierdelarecherchedevaleurssuccessivesest
lidentificationdedoublonsdeva
leurs.Cetteidentificationpeuttreralisegrcelalgorithme adjacent_find.Contrairement
lalgorithme search_n, adjacent_find localisetouslescouplesdevaleursdunesriedevaleurs,
quellequesoitlavaleurdeslmentsdecescouples.Ilestdoncinutiledeprcisercettevaleur,etles
surchargesdecetalgorithmesontdclarescommesuitdanslentte algorithm :
template <classForwardIterator>
ForwardIteratoradjacent_find(ForwardIteratorpremier,ForwardIteratordernier);
template <classForwardIterator,classBinaryPredicate>
ForwardIteratoradjacent_find(ForwardIteratorpremier,ForwardIteratordernier,
BinaryPredicatep);
Lacomplexitdecetalgorithmeestlinaireenfonctiondelatailledelasquencedevaleursdans
laquellelarecherchesefait.
18.3.Oprationsdordonnancement
Labibliothquestandardfournitplusieursalgorithmesrelatifslordonnancementdeslmentsdans
lesconteneurs. Grcecesalgorithmes, ilestpossiblederorganiserlasquencedeceslments
405
Chapitre18.Lesalgorithmes
demanireobtenircertainespropritsbasessurlarelationdordre.Cesrorganisationsontgn
ralementpourbutsoitdetriercompltementcessquences,soitdeffectuerdestrispartielspartir
desquelsilestpossibledobtenirdesinformationsrelativeslordredeslmentsdemaniretrs
efficace.
Laplupartdesalgorithmesdetrietdordonnancementsebasentsurunestructurededonnestrs
performante:les tas .Lesalgorithmesdemanipulationdecesstructuresdedonnesserontdonc
dcritsenpremier.Lessectionsquisuivronttraiterontensuitedesalgorithmesdetrietderecherches
binairesdansunensembledlmentsdjtri.
18.3.1.Oprationsdegestiondestas
Untas(heapenanglais)estunestructurededonnesrcursivedanslaquellelepremierlment
esttoujoursleplusgrandlmentetquidisposeduneoprationdesuppressiondupremierlment
ainsiqueduneoprationdajoutdunnouvellmentextrmementperformantes.Plusprcisment,
lespropritsfondamentalesdestassontlessuivantes:
lepremierlmentdutasesttoujoursleplusgranddetousleslmentscontenus;
ilestpossibledesupprimercepremierlmentetcetteoprationdesuppressionaunecomplexit
logarithmiqueenfonctiondunombredlmentsdansletas;
ilestpossibledajouterunnouvellmentdansletasavecunecomplexitgalementlogarithmique
enfonctiondunombredlmentsdjprsents.
Lestassontdoncparticulirementadaptspourraliserlesfilesdeprioritpuisqueladtermination
duplusgrandlmentestimmdiateetquelasuppressiondecetlmentsefaitavecunecomplexit
logarithmique.Lestassontgalementtrsutilesdanslimplmentationdesalgorithmesdetricarils
permettentdatteindreunecomplexitalgorithmiqueen nln(n),cequiestloptimum.
Note:Enpratique, untasest uneformedarbrebinairequilibrdont lapropritrcursive
est quelaracinedelarbreest llment deplusgrandevaleuret quelesdeuxbranchesde
larbresonteuxmmedestas.Lasuppressiondelaracine,ainsiquelajoutdunnouvellment,
ncessiteunerorganisationdelarbrebinaire, cequi nepeut dpasser ln(n) oprationsen
raisondesonaspectquilibr.
Notezquelestasnegarantissentpas,contrairementauxBarbresetauxarbresrougesetnoirs,
quetousleslmentssituslagauchedunnoeudsontplusgrandsquelenoeudluimmeet
quetousleslmentssitusladroitesontpluspetits.Cestpourcetteraisonquuntasnest
justementpascompltementtri,etquelesalgorithmesdegestiondestasnefontqueconserver
cetordrepartiel.
Lareprsentationdestasenmmoirepeuttrerelativementdifficilecomprendre.Engnral,
il estdusagedelesstockerdansdestableaux,carlesoprationsdegestiondestasrequirent
desitrateursaccsalatoiressurleconteneursurlequel
ellestravaillent. Danscecas, les
premierslmentsdutableaustockentlesnoeudsdelarbrebinairedutas,etlesfeuillessont
placesdanslasecondemoitidutableau. Ainsi, unlment dindice i acommefeuillesles
lmentsdindice 2i et 2i+1 (pourtout i < n/2).Reportezvouslabibliographiepourplus
derenseignementssurlesstructuresdedonnesetlesnotionsalgorithmiquesassocies.
Lesalgorithmesdemanipulationdestassontdclarscommesuitdanslentte algorithm :
template <classRandomAccessIterator
>
voidmake_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier);
406
Chapitre18.Lesalgorithmes
template <classRandomAccessIterator,classCompare
>
voidmake_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier,
Comparec);
template <classRandomAccessIterator
>
voidpop_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier);
template <classRandomAccessIterator,classCompare
>
voidpop_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier,
Comparec);
template <classRandomAccessIterator
>
voidpush_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier);
template <classRandomAccessIterator,classCompare
>
voidpush_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier,
Comparec);
template <classRandomAccessIterator
>
voidsort_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier);
template <classRandomAccessIterator,classCompare
>
voidsort_heap(RandomAccessIteratorpremier,RandomAccessIteratordernier,
Comparec);
407
Chapitre18.Lesalgorithmes
inti;
for(i=0;i <10;++i)
cout << t[i] << "";
cout << endl;
//Supprimellmentdette:
pop_heap(t,t+10);
//Llmentdetteestenposition9:
cout << "Max=" << t[9] << endl;
//Affichelenouveautas:
for(i=0;i <9;++i)
cout << t[i] << "";
cout << endl;
//Ajouteunlment:
t[9]=6;
push_heap(t,t+10);
//Affichelenouveautas:
for(i=0;i <10;++i)
cout << t[i] << "";
cout << endl;
//Triletas:
sort_heap(t,t+10);
//Afficheletableauainsitri:
for(i=0;i <10;++i)
cout << t[i] << "";
cout << endl;
return0;
}
18.3.2.Oprationsdetri
Lesoprationsdetridelabibliothquestandardsappuientsurlesalgorithmesdemanipulationdestas
quelonvientdevoir.Cesmthodespermettentdeffectueruntritotaldeslmentsdunesquence,
untri stable, lgrement moinsperformant queleprcdent maispermettant deconserverlordre
relatifdeslmentsquivalents,etuntripartiel.
Lesalgorithmesdetrisontdclarscommesuitdanslentte algorithm :
template <classRandomAccessIterator
>
voidsort(RandomAccessIteratorpremier,RandomAccessIteratordernier);
template <classRandomAccessIterator,classCompare
>
voidsort(RandomAccessIteratorpremier,RandomAccessIteratordernier,
Comparec);
template <classRandomAccessIterator
>
voidstable_sort(RandomAccessIteratorpremier,RandomAccessIteratordernier);
template <classRandomAccessIterator,classCompare
>
voidstable_sort(RandomAccessIteratorpremier,RandomAccessIteratordernier,
Comparec);
408
Chapitre18.Lesalgorithmes
lmentsdelasquencetrier. Cependant, ilestgalementpossibledutiliserunautrecritre, en
spcifiantunfoncteurbinaireentroisimeparamtre.Cefoncteurdoittrecapabledecomparerdeux
lmentsdelasquencetrieretdindiquersilepremierestounonlepluspetitausensdelarelation
dordrequilutilise.
Exemple1820.Algorithmedetri
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={2,3,7,5,4,1,8,0,9,6};
//Trieletableau:
sort(t,t+10);
//Affichelersultat:
inti;
for(i=0;i <10;++i)
cout << t[i] << "";
cout << endl;
return0;
}
Ilsepeutqueplusieurslmentsdelasquencesoientconsidrscommequivalentsparlarelation
dordreutilise.Parexemple,ilestpossibledetrierdesstructuresselonlundeleurschamps,etplu
sieurslmentspeuventavoirlammevaleurdanscechampsanspourautanttrestrictementgaux.
Danscecas,ilpeuttrencessairedeconserverlordrerelatifinitialdeceslmentsdanslasquence
trier.Lalgorithme sort nepermetpasdelefaire,cependant,lalgorithme stable_sort garantit
laconservationdecetordrerelatif,auprixdunecomplexitalgorithmiquelgrementsuprieure.En
effet,lacomplexitde stable_sort est nln2 (n) (o n estlenombredlmentstrier),alorsque
celledelalgorithme sort nestquede nln(n).Hormiscettepetitediffrence,lesdeuxalgorithmes
sontstrictementquivalents.
Danscertainessituations,ilnestpasncessairedeffectueruntritotaldeslments.Eneffet,letrides
premierslmentsdunesquenceseulementoubienseuleladterminationdunimelmentdun
ensemblepeuventtredsirs.ceteffet,labibliothquestandardfournitlesalgorithmessuivants:
template <classRandomAccessIterator
>
voidpartial_sort(RandomAccessIteratorpremier,
RandomAccessIteratorpivot,RandomAccessIteratordernier);
template <classInputIterator,classRandomAccessIterator
>
RandomAccessIteratorpartial_sort_copy(
InputIteratorpremier,InputIteratordernier,
RandomAccessIteratordebut_resultat,RandomAccessIteratorfin_resultat);
template <classRandomAccessIterator,classCompare
>
voidpartial_sort(
RandomAccessIteratorpremier,RandomAccessIteratorfin_tri,
RandomAccessIteratordernier,Comparec);
template <classInputIterator,classRandomAccessIterator,
classCompare>
RandomAccessIteratorpartial_sort_copy(
409
Chapitre18.Lesalgorithmes
InputIteratorpremier,InputIteratordernier,
RandomAccessIteratordebut_resultat,RandomAccessIteratorfin_resultat,
Comparec);
template <classRandomAccessIterator
>
voidnth_element(RandomAccessIteratorpremier,RandomAccessIteratorposition,
RandomAccessIteratordernier);
template <classRandomAccessIterator,classCompare
>
voidnth_element(RandomAccessIteratorpremier,RandomAccessIteratorposition,
RandomAccessIteratordernier, Comparec);
410
Chapitre18.Lesalgorithmes
selonlarelationdordreinduiteparloprateurdinfrioritouparlefoncteurfournienparamtre.
Lacomplexitdelalgorithme nth_element estlinaireenfonctiondunombredlmentsdela
squencetraiter.
Exemple1822.Algorithmedepositionnementdunimelment
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={2,3,9,6,7,5,4,0,1,8};
//Trietousleslmentsunun:
inti;
for(i=0;i <10;++i)
{
nth_element(t,t+i,t+10);
cout << "Llment" << i <<
"apourvaleur" << t[i] << endl;
}
return0;
}
Cesdeuxalgorithmesprennentenparamtredeuxitrateurspermettantdedfinirlasquencedes
lmentsdontleminimumetlemaximumdoiventtredtermins.Ilsretournentunitrateurrf
renantrespectivementlepluspetitetleplusgranddeslmentsdecettesquence.Lacomplexitde
cesalgorithmesestproportionnellelatailledelasquencefournieenparamtre.
Exemple1823.Algorithmesdedterminationdumaximumetduminimum
#include <iostream>
#include <algorithm>
usingnamespacestd;
411
Chapitre18.Lesalgorithmes
intmain(void)
{
intt[10]={5,2,4,6,3,7,9,1,0,8};
//Afficheleminimumetlemaximum:
cout << *min_element(t,t+10) << endl;
cout << *max_element(t,t+10) << endl;
return0;
}
18.3.3.Oprationsderecherchebinaire
Lesoprationsderecherchebinairedelabibliothquestandardsontdesoprationsquipermettentde
manipulerdessquencesdlmentsdjtriesensebasantsurcetordre.Lesprincipalesfonctionna
litsdecesalgorithmessontderechercherlespositionsdeslmentsdanscessquencesenfonction
deleurvaleur.
Les principaux algorithmes de recherche binaire sont les algorithmes lower_bound et
upper_bound.Cesalgorithmessontdclarscommesuitdanslentte algorithm :
template <classForwardIterator,classT >
ForwardIteratorlower_bound(ForwardIteratorpremier,ForwardIteratordernier,
constT&valeur);
template <classForwardIterator,classT,classCompare>
ForwardIteratorlower_bound(ForwardIteratorpremier,ForwardIteratordernier,
constT&valeur,Comparec);
template <classForwardIterator,classT >
ForwardIteratorupper_bound(ForwardIteratorpremier,ForwardIteratordernier,
constT&valeur);
template <classForwardIterator,classT,classCompare>
ForwardIteratorupper_bound(ForwardIteratorpremier,ForwardIteratordernier,
constT&valeur,Comparec);
412
Chapitre18.Lesalgorithmes
constT&valeur,Comparecomp);
Cetalgorithmerenvoieunepaireditrateurscontenantrespectivementlapremireetladerniredes
positionsauxquelleslavaleurvaleur peuttreinsresansperturberlordredelasquenceidentifie
parlesitrateurs premier et dernier.
Exemple1824.Algorithmesdedterminationdesbornesinfrieuresetsuprieures
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={1,2,4,4,4,5,8,9,15,20};
//Dterminelespositionspossiblesdinsertion
//dun4:
cout << "4peuttreinsrde"
<<
lower_bound(t,t+10,4)t <<
"" <<
upper_bound(t,t+10,4)t << endl;
//Rcuprecespositionsdirectement
//avecequal_range:
pair<int*,int* > p=equal_range(t,t+10,4);
cout << "Equalrangedonnelintervalle["<<
p.firstt << "," << p.secondt << "]";
cout << endl;
return0;
}
413
Chapitre18.Lesalgorithmes
Note:Larelationdquivalenceutiliseparcetalgorithmenestpascelleinduiteparloprateur
dgalitdeslments.Enralit,deuxlments x et y sontconsidrscommequivalentssi
et seulement si lesdeuxinquations x<y et y<x sont fausses. Cest laraisonpourlaquellele
foncteurfournienparamtrenedoitpasdfinirlarelationdgalit,maislarelationdinfriorit.
Cettedistinctionasonimportancesicertainslmentsdelasquencenesontpascomparables
ousi loprateurdgalitdfinituneautrerelationqueloprateurdinfriorit.Bienentendu,en
pratique,cesdeuxinquationssignifiesouventquelesvaleursx et y sontgales.
Exemple1825.Algorithmederecherchebinaire
#include <iostream>
#include <string>
#include <algorithm>
usingnamespacestd;
structA
{
intnumero;
stringnom;
//Numrouniquedellment
//Nomdellment
A(constchar*s):
nom(s)
{
//Affecteunnouveaunumro:
staticinti=0;
numero=++i;
}
//Oprateurdeclassement:
booloperator<(constA&a)const
{
return(numero < a.numero);
}
//Oprateurdgalit(jamaisutilis):
booloperator==(constA&a)const
{
return(nom==a.nom);
}
};
intmain(void)
{
//Construituntableaudlmentstris
//(parconstruction,puisquelenumroestincrment
//chaquenouvelobjet):
At[5]={"Jean","Marc","Alain","Ariane","Sophie"};
//Cetteinstancealemmenomquet[1]
//maisneserapastrouvcarsonnumroestdiffrent:
Atest("Marc");
//Effectuelarecherchedetestdansletableau:
if(binary_search(t,t+5,test))
{
cout << "(" << test.numero << "," <<
414
Chapitre18.Lesalgorithmes
test.nom << ")attrouv" << endl;
}
else
{
cout << "(" << test.numero << "," <<
test.nom << ")napasttrouv"
<< endl;
}
return0;
}
Lacomplexitalgorithmiquedetouscesalgorithmesest
logarithmiqueenfonctiondunombre
dlmentsdelasquencesurlaquelleilstravaillent.Ilssappuientsurlefaitquecettesquenceest
djtriepouratteindrecetobjectif.
18.4.Oprationsdecomparaison
Afindefaciliterlacomparaisondeconteneursdenaturesdiffrentespourlesquels,
desurcrot, il
nexistepasforcment doprateursdecomparaison, labibliothquestandardfournit plusieursal
gorithmesdecomparaison. Cesalgorithmessont capablesdeffectuerunecomparaisonlment
lmentdesdiffrentsconteneurspourvrifierleurgalitentermedlmentscontenus,oudedter
minerunerelationdordreausenslexicographique.Enfin,ilestpossiblededterminerleslments
parlesquelsdeuxconteneurssediffrencient.
Lalgorithmegnraldecomparaisondesconteneursestlalgorithme equal.Cetalgorithmeestd
clarcommesuitdanslentte algorithm :
template <classInputIterator1,classInputIterator2
>
boolequal(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2);
template <classInputIterator1,classInputIterator2,classBinaryPredicate
>
boolequal(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,BinaryPredicatep);
equal prendenparamtre
Commevouspouvezleconstaterdaprscettedclaration,lalgorithme
uncoupleditrateursdcrivantlasquencedlmentsquidoiventtreprisencomptedanslacom
paraisonainsiquunitrateursurlepremierlmentdudeuximeconteneur.Leslmentsrfrencs
successivement parlesitrateurs premier1 et premier2 sont ainsi compars, jusqucequune
diffrencesoitdtecteouquelitrateur dernier1 dupremierconteneursoitatteint.Lavaleurre
tourneest true silesdeuxsquencesdlmentsdesdeuxconteneurssontgaleslmentlment,
et false sinon.Bienentendu,ilestpossibledespcifierunfoncteurbinairequelalgorithmedevra
utiliserpourraliserlescomparaisonsentreleslmentsdesdeuxconteneurs.
Silestspcifi, ce
foncteurestutilispourdterminersileslmentscomparssontgauxounon.
Note:Notezbienici quelefoncteurfourni permetdetesterlgalitdedeuxlmentsetnon
linfriorit,commecestlecasaveclaplupartdesautresalgorithmes.
Silsavrequelesdeuxconteneursnesontpasgauxmembremembre,ilpeuttreutilededter
minerlesitrateursdesdeuxlmentsquiontfaitchouerletestdgalit.Celapeuttreralis
laidedelalgorithme mismatch dontontrouveraladclarationdanslentte algorithm :
415
Chapitre18.Lesalgorithmes
template <classInputIterator1,classInputIterator2
>
pair<InputIterator1,InputIterator2
>
mismatch(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2);
template <classInputIterator1,classInputIterator2,classBinaryPredicate
>
pair<InputIterator1,InputIterator2
>
mismatch(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,BinaryPredicatep);
<<
Enfin,labibliothquestandardfournitunalgorithmedecomparaisongnralpermettantdedtermi
nersiunconteneurestinfrieurunautreconteneurselonlarelationdordrelexicographiqueinduite
parloprateurdinfrioritdutypedeleurslments.Rappelonsquelordrelexicographiqueestce
luiutilisparledictionnaire:leslmentssontexaminsununetdansleurordredapparitionet
lacomparaisonsarrtedsquedeuxlmentsdiffrentssonttrouvs.Encasdgalittotale,leplus
petitdesconteneursestceluiquicontientlemoinsdlments.
Lalgorithmedecomparaisonlexicographiqueestlalgorithme lexicographical_compare.Ilest
dclarcommesuitdanslentte algorithm :
template <classInputIterator1,classInputIterator2
>
boollexicographical_compare(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2);
template <classInputIterator1,classInputIterator2,classCompare
>
416
Chapitre18.Lesalgorithmes
boollexicographical_compare(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
Comparec);
Cet algorithmeprendenparamtredeuxcouples
ditrateurs grceauxquels leprogrammeur
peut spcifier lesdeuxsquencesdlmentscomparer
selonlordrelexicographique. Comme
laccoutume, il est galement possible de fournir un foncteur utiliser pour les tests
dinfriorit entre les lments des deux conteneurs. La valeur retourne par lalgorithme
lexicographical_compare est true si lepremierconteneurest strictement pluspetit quele
deuximeet false sinon.
Exemple1827.Algorithmedecomparaisonlexicographique
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt1[10]={5,6,4,7,8,9,2,1,3,0};
intt2[10]={5,6,4,7,9,2,1,8,3,0};
//Comparelesdeuxtableaux:
if(lexicographical_compare(t1,t1+10,t2,t2+10))
{
cout << "t1estpluspetitquet2" << endl;
}
return0;
}
Touscesalgorithmesdecomparaisonsexcutentavecunecomplexitlinaireenfonctiondunombre
dlmentscomparer.
18.5.Oprationsensemblistes
Enmathmatiques,ilestpossibledeffectuerdiffrentstypesdoprationssurlesensembles.Cesop
rationscomprennentladterminationdelinclusiondunensembledansunautre,leurunion(cest
direleregroupementdetousleurslments),leurintersection(laslectiondeleurslmentscom
muns),leurdiffrence(lasuppressiondeslmentsdunensemblequiappartiennentaussiunautre
ensemble)etleurpartitionnement(ledcoupagedunensembleensousensembledontleslments
vrifientunepropritdiscriminante).
Labibliothquestandardfournittoutunensembledalgorithmesquipermettentdeffectuerlesop
rationsensemblistesclassiquessurlesconteneurstris.Touscesalgorithmessontdcritscidessous
etsontclasssselonlanaturedesoprationsquilsralisent.
Note:Remarquezici quelanotiondetri est importante: lesalgorithmessappuient surcette
propritdesconteneurspoureffectuerleurtravail.Encontrepartiedecettecontrainte,lesper
formancesdecesalgorithmessontexcellentes.
417
Chapitre18.Lesalgorithmes
18.5.1.Oprationsdinclusion
Linclusiondunensembledansunautrepeuttreraliselaidedelalgorithme
algorithmeestdclarcommesuitdanslentte algorithm :
includes.Cet
template <classInputIterator1,classInputIterator2
>
boolincludes(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2);
template <classInputIterator1,classInputIterator2,classCompare
>
boolincludes(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,Comparec);
Exemple1828.Algorithmededterminationdinclusion
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt1[10]={0,1,2,3,4,5,6,7,8,9};
intt2[3]={4,5,6};
if(includes(t1,t1+10,t2,t2+3))
cout << "t1contientt2" << endl;
return0;
}
418
Chapitre18.Lesalgorithmes
18.5.2.Oprationsdintersection
Lintersectiondedeuxensemblespeuttreraliselaidedelalgorithmeset_intersection.Cet
algorithmeestdclardelamaniresuivantedanslentte algorithm :
template <classInputIterator1,classInputIterator2,
classOutputIterator>
OutputIteratorset_intersection(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination);
template <classInputIterator1,classInputIterator2,
classOutputIterator,classCompare >
OutputIteratorset_intersection(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination,Comparec);
Cet algorithmeprendenparamtrelesitrateursdedbut
et defindesdeuxconteneursdont
lintersectiondoittredtermine,ainsiquunitrateurrfrenantlemplacementdestinationoles
lmentsdelintersectiondoiventtrestocks.Pourceuxquiledsirent,ilestgalementpossiblede
spcifierunfoncteurquelalgorithmeutiliserapoureffectuerlescomparaisonsdinfrioritentreles
lmentsdesdeuxconteneursfournisenparamtre.Cefoncteurdevrabienentendutrecompatible
aveclarelationdordreselonlaquellelesconteneurspasssenparamtresonttris.
Lalgorithmecopielemplacementdestinationtousleslmentsdupremierconteneurquifontga
lementpartiedudeuxime.Lecritredappartenanceunensembleest,commepourlalgorithme
includes,lefaitquilexisteaumoinsunlmentdansledeuximeensemblegalllmentconsi
dr.Demme,siplusieurscopiesdunmmelmentsetrouventdanschaqueensemble,lenombre
decopiesdelintersectionseralepluspetitnombredecopiesdellmentdanslesdeuxensembles
sources.
Exemple1829.Algorithmedintersectiondensembles
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt1[10]={2,4,6,8,9,10,15,15,15,17};
intt2[10]={1,4,5,8,11,15,15,16,18,19};
intt[10];
//Effectuelintersectiondet1etdet2:
int*fin=set_intersection(t1,t1+10,t2,t2+10,t);
//Affichelersultat:
int*p=t;
while(p!=fin)
{
cout << *p << "";
++p;
}
cout << endl;
return0;
}
419
Chapitre18.Lesalgorithmes
Lacomplexitdelalgorithmeest n+m,o n et m sontrespectivementlestaillesdesdeuxconteneurs
quiluisontfournisenparamtre.
18.5.3.Oprationsdunionetdefusion
Labibliothquestandardfournit plusieursalgorithmespermettant deraliserluniondedeuxen
sembles. Cesvariantessedistinguentparlamanirequellesontdetraiterlecasdeslmentsen
multiplesexemplaires.
Lalgorithme set_union considrequeleslmentsquivalentsdesdeuxensemblessontlesmmes
entitsetnelesplacequuneseulefoisdanslensemblersultatdelunion.Toutefois,siceslments
sontenplusieursexemplairesdansundesensemblessource,ilsapparatrontgalementenplusieurs
exemplairesdanslersultat.Autrementdit,lenombredlmentsprsentsdanslensembledestina
tionestlenombremaximumducomptedesesoccurrencesdanschacundesdeuxensemblessource.
Inversement,lalgorithme merge effectueuneunionausenslargeetajouteleslmentsdechaqueen
sembledanslensemblersultatsansconsidrerleursvaleurs.Ainsi,lenombredlmentsdursultat
eststrictementgallasommedesnombresdeslmentsdechaqueconteneursource.
Afindedistinguercesdeuxcomportements,onpeutdirequelalgorithme set_union raliselunion
desdeuxensembles,alorsquelalgorithme merge raliseleurfusion.
Touscesalgorithmessontdclarscommesuitdanslentte algorithm :
template <classInputIterator1,classInputIterator2,
classOutputIterator>
OutputIteratorset_union(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination);
template <classInputIterator1,classInputIterator2,
classOutputIterator,classCompare >
OutputIteratorset_union(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination,Comparec);
template <classInputIterator1,classInputIterator2,classOutputIterator
>
OutputIteratormerge(InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination);
template <classInputIterator1,classInputIterator2,
classOutputIterator,classCompare >
OutputIteratormerge(InputIterator1premier1,InputIterator1dernier1,
InputIterator2dernier2,InputIterator2premier2,
OutputIteratordestination,Comparec);
Commevouspouvezleconstater,ilsprennenttousenparamtrelesitrateurspermettantdespcifier
lesdeuxensemblesainsiquunitrateur destination indiquantlemplacementoleslmentsde
lunionoudelafusiondoiventtrestocks. Enfin, sileprogrammeurledsire, ilpeutgalement
donnerlefoncteurdfinissantlarelationdordreselonlaquellelesensemblessonttris.
420
Chapitre18.Lesalgorithmes
Exemple1830.Algorithmesdunionetdefusiondensembles
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt1[4]={1,2,5,5};
intt2[6]={3,4,5,5,5,7};
intt[10];
//Effectueluniondet1etdet2:
int*fin=set_union(t1,t1+4,t2,t2+6,t);
//Affichelersultat:
int*p=t;
while(p!=fin)
{
cout << *p << "";
++p;
}
cout << endl;
//Effectuelafusiondet1etdet2:
fin=merge(t1,t1+4,t2,t2+6,t);
//Affichelersultat:
p=t;
while(p!=fin)
{
cout << *p << "";
++p;
}
cout << endl;
return0;
}
Labibliothquestandardfournitgalementuneversionmodifiedelalgorithmemerge dontlebutest
defusionnerdeuxpartiesdunemmesquencedlmentstriesindpendammentlunedelautre.
Cetalgorithmepermetdeffectuerlafusionsurplace,etnetravailledoncquesurunseulconteneur.
Ilsagitdelalgorithme inplace_merge,quiestdclarcommesuit:
template <classBidirectionalIterator
>
voidinplace_merge(BidirectionalIteratorpremier,
BidirectionalIteratorseparation,
BidirectionalIteratordernier);
template <classBidirectionalIterator,classCompare
>
voidinplace_merge(BidirectionalIteratorpremier,
BidirectionalIteratorseparation,
BidirectionalIteratordernier,Comparec);
421
Chapitre18.Lesalgorithmes
Exemple1831.Algorithmederunificationdedeuxsousensembles
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt[10]={1,5,9,0,2,3,4,6,7,8};
//Fusionnelesdeuxsousensemblesdet
//(lasparationestautroisimelment):
inplace_merge(t,t+3,t+10);
//Affichelersultat:
inti;
for(i=0;i <10;++i)
{
cout << t[i] << "";
}
cout << endl;
return0;
}
18.5.4.Oprationsdediffrence
Ladiffrenceentredeuxensemblespeuttreraliseaveclalgorithme set_difference.Cetal
gorithmesupprimedupremierensembletousleslmentsdusecond,sincessaire.Chaquelment
nestsupprimquuneseulefois,ainsi,silepremierensemblecontientplusieurslmentsidentiques
etqueledeuximeensembleencontientmoins,leslmentsrsiduelsaprssuppressionserontpr
sentsdansladiffrence.
Labibliothquestandardfournitgalementunalgorithmedesuppressionsymtrique, lalgorithme
set_symmetric_difference, quiconstruitunnouvelensemblecontenanttousleslmentsdes
deuxensemblesquinesetrouventpasdanslautre.Ilsagitenfaitdeluniondesdeuxdiffrences
desdeuxensembles.
Note:Remarquezquelemotsymmetricscritavecdeux m enanglais.Nevoustonnez
doncpasdobtenirdeserreursdecompilationsi vouscrivezset_symmetric_difference la
franaise!
422
Chapitre18.Lesalgorithmes
classOutputIterator,classCompare >
OutputIteratorset_difference(
InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination,Comparec);
template <classInputIterator1,classInputIterator2,classOutputIterator
>
OutputIteratorset_symmetric_difference(
InputIterator1premier,InputIterator1dernier,
InputIterator2premier,InputIterator2dernier2,
OutputIteratordestination);
template <classInputIterator1,classInputIterator2,
classOutputIterator,classCompare >
OutputIteratorset_symmetric_difference(
InputIterator1premier1,InputIterator1dernier1,
InputIterator2premier2,InputIterator2dernier2,
OutputIteratordestination,Comparec);
Ilsprennenttousdeuxpairesditrateursidentifiantlesdeuxensemblesdontladiffrencedoittre
calculeainsiquunitrateurrfrenantlemplacementdestinationdanslequellersultatdoittre
plac.Commelaccoutume,ilestpossibledindiquerlefoncteurpermettantlalgorithmedera
liserlestestsdinfrioritentredeuxlmentsetselonlequellesensemblessonttris.Lacomplexit
decesalgorithmesest n+m,o n et m sontlesnombresdlmentsdesdeuxensemblessurlesquels
lesalgorithmesoprent.
Exemple1832.Algorithmesdediffrencedensembles
#include <iostream>
#include <algorithm>
usingnamespacestd;
intmain(void)
{
intt1[10]={0,1,5,7,7,7,8,8,9,10};
intt2[10]={0,2,3,7,9,11,12,12,13,14};
intt[20];
//Calculeladiffrencedet1etdet2:
int*fin=set_difference(t1,t1+10,t2,t2+10,t);
//Affichelersultat:
int*p=t;
while(p!=fin)
{
cout << *p << "";
++p;
}
cout << endl;
//Calculeladiffrencesymtriquedet1ett2:
fin=set_symmetric_difference(t1,t1+10,t2,t2+10,t);
//Affichelersultat:
int*p=t;
while(p!=fin)
{
cout << *p << "";
423
Chapitre18.Lesalgorithmes
++p;
}
cout << endl;
//Calculeladiffrencesymtriquedet1ett2:
fin=set_symmetric_difference(t1,t1+10,t2,t2+10,t);
//Affichelersultat:
p=t;
while(p!=fin)
{
cout << *p << "";
++p;
}
cout << endl;
return0;
}
18.5.5.Oprationsdepartitionnement
Lalgorithme partition delabibliothquestandardpermetdesparerleslmentsdunensemble
endeuxsousensemblesselonuncritredonn.Leslmentsvrifiantcecritresontplacsentte
delensemble,etleslmentsquinelevrifientpassontplacslafin.Cetalgorithmeestdclar
commesuitdanslentte algorithm :
template <classForwardIterator,classPredicate
>
ForwardIteratorpartition(ForwardIteratorpremier,
ForwardIteratordernier,Predicatep);
Lesparamtresquidoiventtrefourniscetalgorithmesontlesitrateursrfrenantlepremieret
ledernierlmentdelensemblepartitionner,ainsiquunfoncteurunairepermettantdedterminer
siunlmentvrifielecritredepartitionnementounon. Lavaleurretourneestlapositiondela
sparationentrelesdeuxsousensemblesgnrsparloprationdepartition.
Exemple1833.Algorithmedepartitionnement
#include <iostream>
#include <functional>
#include <algorithm>
usingnamespacestd;
boolparity_even(inti)
{
return(i&1)==0;
}
intmain(void)
{
intt[10]={0,1,2,3,4,5,6,7,8,9};
//Partitionneletableauennombrepairs
//etnombreimpairs:
partition(t,t+10,ptr_fun(&parity_even));
//Affichelersultat:
inti;
424
Chapitre18.Lesalgorithmes
for(i=0;i <10;++i)
cout << t[i] << "";
cout << endl;
return0;
}
Comme vous pouvez le constater, cet algorithme sutilise exactement de la mme manire
que lalgorithme partition. Toutefois, il garantit lordre relatif des lments auseindes
sousensemblesgnrsparloprationdepartitionnement. Lacomplexitdecetalgorithmeest n
sil disposedesuffisamment demmoire, et nln(n) danslecascontraire( n tant lataillede
lensemblepartitionner).
425
Chapitre18.Lesalgorithmes
426
Chapitre19.Conclusion
Pourterminer,jerappellerailesprincipalesrglespourraliserdebonsprogrammes.Sansorganisa
tion,aucunlangage,aussipuissantsoitil,nepeutgarantirlesuccsdunprojet.Voicidoncquelques
conseils:
commentezvotrecode, maisnetuezpaslecommentaireenenmettantlolesoprationssont
vraimenttrssimplesoudcritesdansundocumentexterne.Marquezlesrfrencesauxdocuments
externesdanslescommentaires;
Voil.VousconnaissezprsentlaplupartdesfonctionnalitsduC++.Jesprequelalecturedece
coursvousauratutileetagrable.Sivousvoulezensavoirplus,consultezlesDraftPapers,mais
sachezquilssontrellementdifficileslire.Ilsnepeuventvraimentpastreprispourunsupportde
cours.LannexeBdcritlorganisationgnraledecedocumentetdonnequelquesrenseignements
pourfaciliterleurlecture.
Bonnecontinuation...
427
Chapitre19.Conclusion
428
AnnexeA.Prioritsdesoprateurs
CetteannexedonnelaprioritdesoprateursdulangageC++,danslordredcroissant.Cetteprio
ritintervientdanslanalysedetouteexpressionetdansladterminationdesonsens.
Cependant,
lanalysedesexpressionspeuttremodifieenchangeantlesprioritslaidedeparenthses.
TableauA1.Oprateursdulangage
Oprateur
Nomousignification
::
Oprateurdersolutiondeporte
[]
Oprateurdaccsauxlmentsdetableau
()
Oprateurdappeldefonction
type()
Oprateurdetranstypageexplicite
Oprateurdeslectiondemembre
>
Oprateurdeslectiondemembrepardrfrencement
++
Oprateurdincrmentationpostfixe
Oprateurdedcrmentationpostfixe
new
Oprateurdecrationdynamiquedobjets
new[]
Oprateurdecrationdynamiquedetableaux
delete
Oprateurdedestructiondesobjetscrsdynamiquement
delete[]
Oprateurdedestructiondestableauxcrsdynamiquement
++
Oprateurdincrmentationprfixe
Oprateurdedcrmentationprfixe
Oprateurdedrfrencement
&
Oprateurdadresse
Oprateurplusunaire
Oprateurngationunaire
Oprateurdengationlogique
Oprateurdecomplmentun
sizeof
Oprateurdetailledobjet
sizeof
Oprateurdetailledetype
typeid
Oprateurdidentificationdetype
(type)
Oprateurdetranstypage
const_cast
Oprateurdetranstypagedeconstance
dynamic_cast
Oprateurdetranstypagedynamique
reinterpret_cast
Oprateurderinterprtation
static_cast
Oprateurdetranstypagestatique
.*
Oprateurdeslectiondemembreparpointeursurmembre
>*
Oprateurdeslectiondemembreparpointeursurmembrepar
drfrencement
Oprateurdemultiplication
Oprateurdedivision
Oprateurderestedeladivisionentire
429
AnnexeA.Prioritsdesoprateurs
Oprateur
430
Nomousignification
Oprateurdaddition
Oprateurdesoustraction
<<
Oprateurdedcalagegauche
>>
Oprateurdedcalagedroite
<
Oprateurdinfriorit
>
Oprateurdesupriorit
<=
Oprateurdinfrioritoudgalit
>=
Oprateurdesuprioritoudgalit
==
Oprateurdgalit
!=
Oprateurdingalit
&
Oprateuretbinaire
Oprateurouexclusifbinaire
Oprateurouinclusifbinaire
&&
Oprateuretlogique
||
Oprateuroulogique
?:
Oprateurternaire
Oprateurdaffectation
*=
Oprateurdemultiplicationetdaffectation
/=
Oprateurdedivisionetdaffectation
%=
Oprateurdemoduloetdaffectation
+=
Oprateurdadditionetdaffectation
Oprateurdesoustractionetdaffectation
<<=
Oprateurdedcalagegaucheetdaffectation
>>=
Oprateurdedcalagedroiteetdaffectation
&=
Oprateurdeetbinaireetdaffectation
|=
Oprateurdeouinclusifbinaireetdaffectation
^=
Oprateurdeouexclusifbinaireetdaffectation
Oprateurvirgule
AnnexeB.DraftPapers
LesDraftPaperssontvraimentunesourcedinformationstrsprcise,maisilsnesontpasvraiment
structurs.Enfait,ilsnesontdestinsquauxditeursdelogicielsdsirantraliseruncompilateur,et
lastructuredudocumentressembleuntextedeloi(fortementtechniqueenprime).Lesexemplesy
sontrares,etquandilyena,onnesaitpasquelparagrapheilsserfrent.Enfin,nombredetermes
nondfinissontutiliss,etilfautlireledocumentpendantquelques40pagesavantdecommencer
lecomprendre.
Afindefaciliterleurlecture,jedonneiciquelquesdfinitions,ainsiquelastructuredesDraftPapers.
LesDraftPaperssontconstitusdedeuxgrandesparties.Lapremiretraitedulangage,desasyntaxe
etdesasmantique.LadeuximepartiedcritlabibliothquestandardC++.
LasyntaxeestdcritedanslapremirepartiedelamanireBNF.Ilvautmieuxtrefamiliarisavec
cetteformededescriptionpourlacomprendre. Celanecauserapasdeproblmecependantsilon
matrisedjlasyntaxeduC++.
Lorsdelalecturedeladeuximepartie,onnesattarderapastropsurlesfonctionnalitsdegestion
deslanguesetdesjeuxdecaractres(locales).Ellesnesontpasncessaireslacomprhensiondela
bibliothquestandard.Unefoislesgrandsprincipesdelabibliothqueassimils,lesnotionsdelocale
pourronttreapprofondies.
Lestermessuivantssont souvent utilisset nondfinis(oudfinisaumilieududocument dune
manirepeuclaire).Leursdfinitionspourronttredungrandsecourslorsdelecturedelapremire
partiedesDraftPapers:
unagrgatestuntableauouuneclassequinapasdeconstructeurs,pasdefonctionsvirtuelles,et
pasdedonnenonstatiqueprivateouprotected;
POD:cetteabrviationsignifieplainoldata,cequinestpascomprhensibleapriori.Enfait,un
typePODestuntyperelativementsimple,pourlequelaucuntraitementparticuliernestncessaire
(pasdeconstructeur,pasdevirtualit,etc.).LadfinitiondestypesPODestrcursive:unestructure
ouuneunionestuntypePODsicestunagrgatquinecontientpasdepointeursurunmembrenon
statique,pasderfrence,pasdetypenonPOD,pasdeconstructeurdecopieetpasdedestructeur.
Lesautrestermessontdfinislorsquilsapparaissentpourlapremirefoisdansledocument.
431
AnnexeB.DraftPapers
432
AppendixC.GNUFreeDocumentation
License
Version1.1,March2000
Copyright(C)2000FreeSoftwareFoundation,Inc.
59TemplePlace,Suite330,Boston,MA021111307USA
Everyoneispermittedtocopyanddistributeverbatimcopiesofthislicensedocument,butchanging
itisnotallowed.
0.PREAMBLE
ThepurposeofthisLicenseistomakeamanual,textbook,orotherwrittendocument"free"inthe
senseoffreedom:toassureeveryonetheeffectivefreedomtocopyandredistributeit,withorwithout
modifyingit, eithercommerciallyornoncommercially. Secondarily, thisLicensepreservesforthe
authorandpublisherawaytogetcreditfortheirwork,whilenotbeingconsideredresponsiblefor
modificationsmadebyothers.
ThisLicenseisakindof"copyleft",whichmeansthatderivativeworksofthedocumentmustthem
selvesbefreeinthesamesense.ItcomplementstheGNUGeneralPublicLicense,whichisacopyleft
licensedesignedforfreesoftware.
WehavedesignedthisLicenseinordertouseitformanualsforfreesoftware,becausefreesoftware
needsfreedocumentation:afreeprogramshouldcomewithmanualsprovidingthesamefreedoms
thatthesoftwaredoes. ButthisLicenseisnotlimitedtosoftwaremanuals;itcanbeusedforany
textualwork,regardlessofsubjectmatterorwhetheritispublishedasaprintedbook.Werecommend
thisLicenseprincipallyforworkswhosepurposeisinstructionorreference.
1.APPLICABILITYANDDEFINITIONS
ThisLicenseappliestoanymanualorotherworkthatcontainsanoticeplacedbythecopyrightholder
sayingitcanbedistributedunderthetermsofthisLicense.The"Document",below,referstoanysuch
manualorwork.Anymemberofthepublicisalicensee,andisaddressedas"you".
A"ModifiedVersion"oftheDocumentmeansanyworkcontainingtheDocumentoraportionofit,
eithercopiedverbatim,orwithmodificationsand/ortranslatedintoanotherlanguage.
A"SecondarySection"isanamedappendixorafrontmattersectionoftheDocumentthatdeals
exclusivelywiththerelationshipofthepublishersorauthorsoftheDocument totheDocuments
overallsubject(ortorelatedmatters)andcontainsnothingthatcouldfalldirectlywithinthatoverall
subject. (Forexample, iftheDocumentisinpartatextbookofmathematics,
aSecondarySection
maynotexplainanymathematics.)Therelationshipcouldbeamatterofhistoricalconnectionwith
thesubjectorwithrelatedmatters,oroflegal,commercial,philosophical,ethicalorpoliticalposition
regardingthem.
The"InvariantSections"arecertainSecondarySectionswhosetitlesaredesignated,asbeingthoseof
InvariantSections,inthenoticethatsaysthattheDocumentisreleasedunderthisLicense.
The"CoverTexts"arecertainshortpassagesoftextthatarelisted, asFrontCoverTextsorBack
CoverTexts,inthenoticethatsaysthattheDocumentisreleasedunderthisLicense.
A"Transparent"copyoftheDocument meansamachinereadablecopy, representedinaformat
whosespecificationisavailabletothegeneralpublic,whosecontentscanbeviewedandediteddi
rectlyandstraightforwardlywithgenerictexteditorsor(forimagescomposedofpixels)genericpaint
programsor(fordrawings)somewidelyavailabledrawingeditor,andthatissuitableforinputtotext
formattersorforautomatictranslationtoavarietyofformatssuitableforinputtotextformatters.
433
AppendixC.GNUFreeDocumentationLicense
AcopymadeinanotherwiseTransparentfileformatwhosemarkuphasbeendesignedtothwartor
discouragesubsequentmodificationbyreadersisnotTransparent.Acopythatisnot"Transparent"is
called"Opaque".
ExamplesofsuitableformatsforTransparentcopiesincludeplainASCIIwithoutmarkup, Texinfo
inputformat, LaTeXinputformat, SGMLorXMLusingapubliclyavailableDTD, andstandard
conformingsimpleHTMLdesignedforhumanmodification. OpaqueformatsincludePostScript,
PDF, proprietaryformatsthatcanbereadandeditedonlybyproprietarywordprocessors,
SGML
orXMLforwhichtheDTDand/orprocessingtoolsarenotgenerallyavailable,
andthemachine
generatedHTMLproducedbysomewordprocessorsforoutputpurposesonly.
The"TitlePage"means, foraprintedbook, thetitlepageitself, plussuchfollowingpagesasare
neededtohold, legibly, thematerialthisLicenserequirestoappearinthetitlepage. Forworksin
formatswhichdonothaveanytitlepageassuch,"TitlePage"meansthetextnearthemostprominent
appearanceoftheworkstitle,precedingthebeginningofthebodyofthetext.
2.VERBATIMCOPYING
YoumaycopyanddistributetheDocumentinanymedium,eithercommerciallyornoncommercially,
providedthatthisLicense,thecopyrightnotices,andthelicensenoticesayingthisLicenseapplies
totheDocumentarereproducedinallcopies, andthatyouaddnootherconditionswhatsoeverto
thoseofthisLicense.Youmaynotusetechnicalmeasurestoobstructorcontrolthereadingorfurther
copyingofthecopiesyoumakeordistribute.However,youmayacceptcompensationinexchange
forcopies.Ifyoudistributealargeenoughnumberofcopiesyoumustalsofollowtheconditionsin
section3.
Youmayalsolendcopies, underthesameconditionsstatedabove, andyoumaypubliclydisplay
copies.
3.COPYINGINQUANTITY
IfyoupublishprintedcopiesoftheDocumentnumberingmorethan100,andtheDocumentslicense
noticerequiresCoverTexts,youmustenclosethecopiesincoversthatcarry,clearlyandlegibly,all
theseCoverTexts:FrontCoverTextsonthefrontcover, andBackCoverTextsonthebackcover.
Bothcoversmustalsoclearlyandlegiblyidentifyyouasthepublisherofthesecopies.
Thefront
covermustpresentthefulltitlewithallwordsofthetitleequallyprominentandvisible.Youmayadd
othermaterialonthecoversinaddition.Copyingwithchangeslimitedtothecovers,aslongasthey
preservethetitleoftheDocumentandsatisfytheseconditions,canbetreatedasverbatimcopyingin
otherrespects.
Iftherequiredtextsforeithercoveraretoovoluminoustofitlegibly,youshouldputthefirstones
listed(asmanyasfitreasonably)ontheactualcover,andcontinuetherestontoadjacentpages.
IfyoupublishordistributeOpaquecopiesoftheDocumentnumberingmorethan100,youmusteither
includeamachinereadableTransparentcopyalongwitheachOpaquecopy,orstateinorwitheach
OpaquecopyapubliclyaccessiblecomputernetworklocationcontainingacompleteTransparent
copyoftheDocument,freeofaddedmaterial,whichthegeneralnetworkusingpublichasaccessto
downloadanonymouslyatnochargeusingpublicstandardnetworkprotocols. Ifyouusethelatter
option, youmusttakereasonablyprudentsteps, whenyoubegindistributionofOpaquecopiesin
quantity,toensurethatthisTransparentcopywillremainthusaccessibleatthestatedlocationuntil
atleastoneyearafterthelasttimeyoudistributeanOpaquecopy(directlyorthroughyouragentsor
retailers)ofthateditiontothepublic.
Itisrequested,butnotrequired,thatyoucontacttheauthorsoftheDocumentwellbeforeredistribut
inganylargenumberofcopies,togivethemachancetoprovideyouwithanupdatedversionofthe
Document.
4.MODIFICATIONS
434
AppendixC.GNUFreeDocumentationLicense
YoumaycopyanddistributeaModifiedVersionoftheDocumentundertheconditionsofsections
2and3above,providedthatyoureleasetheModifiedVersionunderpreciselythisLicense,withthe
ModifiedVersionfillingtheroleoftheDocument, thuslicensingdistributionandmodificationof
theModifiedVersiontowhoeverpossessesacopyofit.Inaddition,youmustdothesethingsinthe
ModifiedVersion:
A.UseintheTitlePage(andonthecovers,ifany)atitledistinctfromthatoftheDocument,and
fromthoseofpreviousversions(whichshould,iftherewereany,belistedintheHistorysection
oftheDocument).Youmayusethesametitleasapreviousversioniftheoriginalpublisherof
thatversiongivespermission.
B.ListontheTitlePage,asauthors,oneormorepersonsorentitiesresponsibleforauthorshipof
themodificationsintheModifiedVersion,togetherwithatleastfiveoftheprincipalauthorsof
theDocument(allofitsprincipalauthors,ifithaslessthanfive).
C.StateontheTitlepagethenameofthepublisheroftheModifiedVersion,asthepublisher.
D.PreserveallthecopyrightnoticesoftheDocument.
E.Addanappropriatecopyrightnoticeforyourmodificationsadjacenttotheothercopyrightno
tices.
F.Include,immediatelyafterthecopyrightnotices,alicensenoticegivingthepublicpermissionto
usetheModifiedVersionunderthetermsofthisLicense,intheformshownintheAddendum
below.
G.PreserveinthatlicensenoticethefulllistsofInvariantSectionsandrequiredCoverTextsgiven
intheDocumentslicensenotice.
H.IncludeanunalteredcopyofthisLicense.
I.Preservethesectionentitled"History",anditstitle,andaddtoitanitemstatingatleastthetitle,
year, newauthors, andpublisheroftheModifiedVersionasgivenontheTitlePage. Ifthere
isnosectionentitled"History"intheDocument,createonestatingthetitle,year,authors,and
publisheroftheDocumentasgivenonitsTitlePage,thenaddanitemdescribingtheModified
Versionasstatedintheprevioussentence.
J.Preservethenetworklocation,ifany,givenintheDocumentforpublicaccesstoaTransparent
copyoftheDocument,andlikewisethenetworklocationsgivenintheDocumentforprevious
versionsitwasbasedon.Thesemaybeplacedinthe"History"section.Youmayomitanetwork
locationforaworkthatwaspublishedatleastfouryearsbeforetheDocumentitself,orifthe
originalpublisheroftheversionitreferstogivespermission.
K.Inanysectionentitled"Acknowledgements"or"Dedications", preservethesectionstitle, and
preserveinthesectionallthesubstanceandtoneofeachofthecontributoracknowledgements
and/ordedicationsgiventherein.
L.PreservealltheInvariantSectionsoftheDocument, unalteredintheirtextandintheirtitles.
Sectionnumbersortheequivalentarenotconsideredpartofthesectiontitles.
M.Deleteanysectionentitled"Endorsements".SuchasectionmaynotbeincludedintheModified
Version.
N.Donotretitleanyexistingsectionas"Endorsements"ortoconflictintitlewithanyInvariant
Section.
IftheModifiedVersionincludesnewfrontmattersectionsorappendicesthatqualifyasSecondary
SectionsandcontainnomaterialcopiedfromtheDocument,youmayatyouroptiondesignatesome
435
AppendixC.GNUFreeDocumentationLicense
orallofthesesectionsasinvariant.Todothis,addtheirtitlestothelistofInvariantSectionsinthe
ModifiedVersionslicensenotice.Thesetitlesmustbedistinctfromanyothersectiontitles.
Youmayaddasectionentitled"Endorsements", provideditcontainsnothingbutendorsementsof
yourModifiedVersionbyvariouspartiesforexample,statementsofpeerrevieworthatthetexthas
beenapprovedbyanorganizationastheauthoritativedefinitionofastandard.
YoumayaddapassageofuptofivewordsasaFrontCoverText,andapassageofupto25wordsas
aBackCoverText,totheendofthelistofCoverTextsintheModifiedVersion.Onlyonepassageof
FrontCoverTextandoneofBackCoverTextmaybeaddedby(orthrougharrangementsmadeby)
anyoneentity.IftheDocumentalreadyincludesacovertextforthesamecover,previouslyaddedby
youorbyarrangementmadebythesameentityyouareactingonbehalfof,youmaynotaddanother;
butyoumayreplacetheoldone,onexplicitpermissionfromthepreviouspublisherthataddedthe
oldone.
Theauthor(s)andpublisher(s)oftheDocumentdonotbythisLicensegivepermissiontousetheir
namesforpublicityforortoassertorimplyendorsementofanyModifiedVersion.
5.COMBININGDOCUMENTS
YoumaycombinetheDocumentwithotherdocumentsreleasedunderthisLicense,undertheterms
definedinsection4aboveformodifiedversions, providedthatyouincludeinthecombinationall
oftheInvariantSectionsofalloftheoriginaldocuments,unmodified,andlistthemallasInvariant
Sectionsofyourcombinedworkinitslicensenotice.
ThecombinedworkneedonlycontainonecopyofthisLicense,
andmultipleidentical Invariant
Sectionsmaybereplacedwithasinglecopy.IftherearemultipleInvariantSectionswiththesame
namebutdifferentcontents,makethetitleofeachsuchsectionuniquebyaddingattheendofit,in
parentheses,thenameoftheoriginalauthororpublisherofthatsectionifknown,orelseaunique
number.MakethesameadjustmenttothesectiontitlesinthelistofInvariantSectionsinthelicense
noticeofthecombinedwork.
Inthecombination,youmustcombineanysectionsentitled"History"inthevariousoriginaldocu
ments,formingonesectionentitled"History";likewisecombineanysectionsentitled"Acknowledge
ments",andanysectionsentitled"Dedications".Youmustdeleteallsectionsentitled"Endorsements."
6.COLLECTIONSOFDOCUMENTS
YoumaymakeacollectionconsistingoftheDocument andotherdocumentsreleasedunderthis
License, andreplacetheindividual copiesofthisLicenseinthevariousdocumentswithasingle
copythatisincludedinthecollection,providedthatyoufollowtherulesofthisLicenseforverbatim
copyingofeachofthedocumentsinallotherrespects.
Youmayextractasingledocumentfromsuchacollection,anddistributeitindividuallyunderthis
License, providedyouinsert acopyofthisLicenseintotheextracteddocument,
andfollowthis
Licenseinallotherrespectsregardingverbatimcopyingofthatdocument.
7.AGGREGATIONWITHINDEPENDENTWORKS
AcompilationoftheDocumentoritsderivativeswithotherseparateandindependentdocumentsor
works,inoronavolumeofastorageordistributionmedium,doesnotasawholecountasaModified
VersionoftheDocument,providednocompilationcopyrightisclaimedforthecompilation.Sucha
compilationiscalledan"aggregate",andthisLicensedoesnotapplytotheotherselfcontainedworks
thuscompiledwiththeDocument,onaccountoftheirbeingthuscompiled,iftheyarenotthemselves
derivativeworksoftheDocument.
IftheCoverTextrequirementofsection3isapplicabletothesecopiesoftheDocument,thenifthe
Documentislessthanonequarteroftheentireaggregate,theDocumentsCoverTextsmaybeplaced
oncoversthat surroundonlytheDocument withintheaggregate. Otherwisetheymust appearon
coversaroundthewholeaggregate.
436
AppendixC.GNUFreeDocumentationLicense
8.TRANSLATION
Translationisconsideredakindofmodification,soyoumaydistributetranslationsoftheDocument
underthetermsofsection4.ReplacingInvariantSectionswithtranslationsrequiresspecialpermis
sionfromtheircopyrightholders,butyoumayincludetranslationsofsomeorallInvariantSections
inadditiontotheoriginalversionsoftheseInvariantSections.Youmayincludeatranslationofthis
Licenseprovidedthat youalsoincludetheoriginal EnglishversionofthisLicense. Incaseofa
disagreementbetweenthetranslationandtheoriginalEnglishversionofthisLicense, theoriginal
Englishversionwillprevail.
9.TERMINATION
Youmaynotcopy,modify,sublicense,ordistributetheDocumentexceptasexpresslyprovidedfor
underthisLicense.Anyotherattempttocopy,modify,sublicenseordistributetheDocumentisvoid,
andwillautomaticallyterminateyourrightsunderthisLicense.However,partieswhohavereceived
copies,orrights,fromyouunderthisLicensewillnothavetheirlicensesterminatedsolongassuch
partiesremaininfullcompliance.
10.FUTUREREVISIONSOFTHISLICENSE
TheFreeSoftwareFoundationmaypublishnew,revisedversionsoftheGNUFreeDocumentation
Licensefromtimetotime.Suchnewversionswillbesimilarinspirittothepresentversion,butmay
differindetailtoaddressnewproblemsorconcerns.Seehttp://www.gnu.org/copyleft/.
EachversionoftheLicenseisgivenadistinguishingversionnumber.IftheDocumentspecifiesthat
aparticularnumberedversionofthisLicense"oranylaterversion"appliestoit,youhavetheoption
offollowingthetermsandconditionseitherofthatspecifiedversionorofanylaterversionthathas
beenpublished(notasadraft)bytheFreeSoftwareFoundation.IftheDocumentdoesnotspecify
aversionnumberofthisLicense,youmaychooseanyversioneverpublished(notasadraft)bythe
FreeSoftwareFoundation.
437
AppendixC.GNUFreeDocumentationLicense
438
AnnexeD.Licencededocumentationlibre
GNU
Disclaimer
ThisisanunofficialtranslationoftheGNUFreeDocumentationLicenseintoFrench.Itwasnotpu
blishedbytheFreeSoftwareFoundation,anddoesnotlegallystatethedistributiontermsforsoftware
thatusestheGNUFDLonlytheoriginalEnglishtextoftheGNUFDLdoesthat.However,wehope
thatthistranslationwillhelpFrenchspeakersunderstandtheGNUFDLbetter.
CeciestunetraductionfranaisenonofficielledelaLicencededocumentationlibreGNU.Ellenapas
tpublieparlaFreeSoftwareFoundation,etnefixepaslgalementlesconditionsderedistribution
desdocumentsquilutilisentseulletexteoriginalenanglaislefait.Nousespronstoutefoisque
cettetraductionaideralesfrancophonesmieuxcomprendrelaFDLGNU.
TraductionfranaisenonofficielledelaGFDLVersion1.1(Mars2000)
Copyrightoriginal:
Copyright(C)2000FreeSofwareFoundation,inc
59TemplePlace,Suite330,Boston,MA021111307USA
Pourlatraduction:
Version1.0FR(JeanLucFortin,juillet2000)
Version1.1FR(ChristianCasteyde,mars2001)
Version1.1.1FR(CsarAlexanian,mars2001)
Version1.1.2FR(ChristianCasteydeetCsarAlexanian,mars2001)
Version1.1.3FR(ChristianCasteyde,avril2001)
Chacunest libredecopieret dedistribuerdescopiesconformesdecetteLicence,
autorislamodifier.
maisnul nest
0PRAMBULE
LobjetdecetteLicenceestderendretoutmanuel,livreouautredocumentcritlibreausensde
lalibertdutilisation,savoir:assurerchacunlaliberteffectivedelecopieroudeleredistribuer,
avecousansmodifications,commercialementounon.Enoutre,cetteLicencegarantitlauteuret
lditeurlareconnaissancedeleurtravail,sansquilssoientpourautantconsidrscommerespon
sablesdesmodificationsralisespardestiers.
CetteLicenceest unesortedecopyleft , cequi signifiequelestravauxdrivsdudocument
doriginesont euxmmeslibresselonlesmmestermes. EllecompltelaLicencePublique
GnraleGNU,quiestgalementuneLicencecopyleft,conuepourleslogicielslibres.
NousavonsconucetteLicencepourladocumentationdeslogicielslibres,
carleslogicielslibres
ontbesoindunedocumentationellemmelibre:unlogiciellibredoittreaccompagndunmanuel
garantissantlesmmeslibertsquecellesaccordesparlelogicielluimme.MaiscetteLicencenest
paslimiteauxseulsmanuelsdeslogiciels;ellepeuttreutilisepourtouslesdocumentscrits,sans
distinctionparticulirerelativeausujettraitouaumodedepublication.Nousrecommandonslusage
decetteLicenceprincipalementpourlestravauxdestinsdesfinsdenseignementoudevantservir
dedocumentsderfrence.
1APPLICABILITETDFINITIONS
439
AnnexeD.LicencededocumentationlibreGNU
CetteLicencecouvretoutmanueloutoutautretravailcritcontenantunenoticedecopyrightautori
santlaredistributionselonlestermesdecetteLicence.LemotDocumentserfreciaprsun
telmanueloutravail.Toutepersonneenestpardfinitionconcessionnaire,etestrfrenceciaprs
parletermeVous.
UneVersionmodifieduDocumentdsignetouttravailencontenantlatotalitouseulementune
portiondeceluici,copiemotpourmot,modifieet/outraduitedansuneautrelangue.
UneSectionsecondairedsigneuneannexeauDocument,
outouteinformationindiquant les
rapportsentrelauteuroulditeuretlesujet(outoutautresujetconnexe)dudocument, sanstou
tefoistreenrapportdirectaveclesujetluimme(parexemple,sileDocumentestunmanuelde
mathmatiques,uneSectionsecondairenetraiteradaucunenotionmathmatique).Cettesectionpeut
contenirdesinformationsrelativeslhistoriqueduDocument,dessourcesdocumentaires,desdis
positionslgales,commerciales,philosophiques,oudespositionsthiquesoupolitiquessusceptibles
deconcernerlesujettrait.
LesSectionsinaltrablessontdessectionssecondairesconsidrescommenepouvanttremodi
fiesetcitescommetellesdanslanoticelgalequiplaceleDocumentsouscetteLicence.
LesTextesdecouverturesontlestextescourtssitussurlespagesdecouvertureavantetarrire
duDocument,etcitscommetelsdanslamentionlgaledeceDocument.
LetermeCopietransparentedsigneuneversionnumriqueduDocumentreprsentedansun
formatdontlesspcificationssontpubliquementdisponiblesetdontlecontenupeuttrevisualiset
ditdirectementetimmdiatementparunditeurdetextequelconque,ou(pourlesimagescompo
sesdepixels)parunprogrammedetraitementdimagesquelconque,ou(pourlesdessins)parun
diteurdedessinscourant.Ceformatdoittrepouvoirtreacceptdirectementoutreconvertible
facilementdansdesformatsutilisablesdirectementpardeslogicielsdeformatagedetexte.Unecopie
publiedansunquelconqueformatnumriqueouvertmaisdontlastructureatconuedanslebut
exprsdeprvenirlesmodificationsultrieuresduDocumentoudanslebutdendcouragerleslec
teursnestpasconsidrecommeuneCopieTransparente.UnecopiequinestpasTransparente
estconsidre,paropposition,commeOpaque.
LeformatdefichiertextecodenASCIIgnriqueetnutilisantpasdebalises,
lesformatsdefi
chiersTexinfoouLaTeX, lesformatsdefichiersSGMLouXMLutilisantuneDTDpubliquement
accessible, ainsi quelesformatsdefichiersHTMLsimpleet standard, critsdetellesortequils
sontmodifiablessansoutilspcifique,sontdesexemplesdeformatsacceptablespourlaralisation
deCopiesTransparentes. Lesformatssuivantssontopaques:PostScript, PDF, formatsdefichiers
propritairesquinepeuventtrevisualissouditsquepardestraitementsdetextespropritaires,
SGMLetXMLutilisantdesDTDet/oudesoutilsdeformatagequinesontpasdisponiblespublique
ment,etducodeHTMLgnrparunemachinelaideduntraitementdetextequelconqueetdans
leseulbutdelagnrationdunformatdesortie.
LaPagedetitredsigne,pourlesouvragesimprims,lapagedetitreellemme,ainsiqueles
pagessupplmentairesncessairespourfournirclairementlesinformationsdontcetteLicenceimpose
laprsencesurlapagedetitre.PourlestravauxnayantpasdePagedetitrecommedcritcidessus,
laPagedetitredsigneletextequisapparenteleplusautitredudocumentetsituavantletexte
principal.
2COPIESCONFORMES
VouspouvezcopieretdistribuerleDocumentsurtouttypedesupport,
commercialementounon,
conditionquecetteLicence, lanoticedecopyrightetlanoticedelaLicenceindiquantquecette
LicencesappliqueceDocumentsoientreproduitsdanstouteslescopies,etquevousnyajoutiez
aucuneconditionrestrictivesupplmentaire.Vousnepouvezpasutiliserunquelconquemoyentech
niquevisantempcheroucontrlerlalectureoulareproductionultrieuredescopiesquevous
440
AnnexeD.LicencededocumentationlibreGNU
avezcresoudistribues.Toutefois,vouspouvezsolliciterunertributionenchangedescopies.Si
vousdistribuezunegrandequantitdecopies,rfrezvousauxdispositionsdelasection3.
Vouspouvezgalementprterdescopies, souslesmmesconditionsquecellesprcites,
pouvezafficherpubliquementdescopiesdeceDocument.
etvous
3COPIESENNOMBRE
SivouspubliezdescopiesimprimesdeceDocumentplusde100exemplaires,etquelaLicence
duDocumentindiquelaprsencedeTextesdecouverture,vousdevezfournirunecouverturepour
chaquecopie,quiprsentelesTextesdecouverturedespremireetdernirepagesdecouverturedu
Document.Lespremireetdernirepagesdecouverturedoiventgalementvousidentifierclairement
etsansambigutcommetantlditeurdecescopies.Lapremirepagedecouverturedoitcomporter
letitreduDocumentenmotsdimportanceetdevisibilitgale.Vouspouvezajouterdesinformations
complmentairessurlespagesdecouverture.LescopiesduDocumentdontseulelacouvertureat
modifiepeuventtreconsidrescommedescopiesconformes,conditionqueletitreduDocument
soitprservetquelesconditionsindiquesprcdemmentsoientrespectes.
Silestextesdevantsetrouversurlacouverturesonttropimportantspourytenirdemanireclaire,
vouspouvezneplacerquelespremierssurlapremirepageet
placerlessuivantssurlespages
conscutives.
Sivouspubliezplusde100CopiesopaquesduDocument,vousdevezsoitfourniruneCopietrans
parentepourchaqueCopieopaque,soitprciseroufourniravecchaqueCopieopaqueuneadresse
rseaupubliquementaccessibleduneCopietransparenteetcomplteduDocument,sansaucunajout
oumodification,etlaquelletoutlemondepeutaccderentlchargementanonymeetsansfrais,
selondesprotocolesrseaucommunsetstandards.Sivouschoisissezcettedernireoption,vousde
vezprendrelesdispositionsncessaires, danslalimiteduraisonnable, afindegarantirlaccsnon
restrictiflaCopietransparentedurantuneannepleineaprsladiffusionpubliquedeladernire
Copieopaque(directementouviavosrevendeurs).
Nousrecommandons,maiscenestpasobligatoire,quevouscontactiezlauteurduDocumentsuf
fisammenttt avant toutepublicationdungrandnombredecopies, afindelui permettredevous
donneruneversionjourduDocument.
4MODIFICATIONS
VouspouvezcopieretdistribueruneVersionmodifieduDocumentenrespectantlesconditionsdes
sections2et3prcdentes, conditiondeplacercetteVersionmodifiesouslaprsenteLicence,
danslaquelleletermeDocumentdoittreremplacparlestermesVersionmodifie,donnant
ainsilautorisationderedistribueretdemodifiercetteVersionmodifiequiconqueenpossdeune
copie.Deplus,vousdevezeffectuerlesactionssuivantesdanslaVersionmodifie:
A.UtilisersurlaPagedetitre(etsurlapagedecouvertureventuellementprsente)untitredistinct
deceluiduDocumentdorigineetdetoutessesversionsantrieures(qui,siellesexistent,doivent
trementionnesdanslasectionHistoriqueduDocument).Vouspouvezutiliserlemmetitre
silditeurdoriginevousenadonnexpressmentlapermission.
B.MentionnersurlaPagedetitreentant quauteursuneouplusieursdespersonnesouentits
responsablesdesmodificationsdelaVersionmodifie,avecaumoinslescinqprincipauxauteurs
duDocument(outouslesauteurssiilyenamoinsdecinq).
C.PrcisersurlaPagedetitrelenomdelditeurdelaVersionmodifie,
Document.
entantquditeurdu
D.PrserverintgralementtouteslesnoticesdecopyrightduDocument.
E.Ajouterunenoticedecopyrightadjacenteauxautresnoticespourvospropresmodifications.
441
AnnexeD.LicencededocumentationlibreGNU
F.Inclure immdiatement aprs les notices de copyright une notice donnant quiconque
lautorisationdutiliserlaVersionmodifieselonlestermesdecetteLicence,
souslaforme
prsentedanslannexeindiquecidessous.
G.PrserverdanscettenoticelalistecompltedesSectionsinaltrablesetlesTextesdecouverture
donnsaveclanoticedelaLicenceduDocument.
H.InclureunecopienonmodifiedecetteLicence.
I.PrserverlasectionnommeHistoriqueetsontitre,etyajouterunenouvelleentredcrivant
letitre,lanne,lesnouveauxauteursetlditeurdelaVersionmodifie,telsquedcritssurla
Pagedetitre,ainsiquundescriptifdesmodificationsapportesdepuislaprcdenteversion.
J.ConserverladresserseauventuellementindiquedansleDocumentpermettantquiconque
daccderuneCopietransparenteduDocument,ainsiquelesadressesrseauindiquesdansle
DocumentpourlesversionsprcdentessurlesquellesleDocumentsebase.Ceslienspeuvent
treplacsdanslasectionHistorique.Vouspouveznepasconserverleslienspouruntravail
datantdeplusdequatreansavantlaversioncouranteousilditeurdoriginevousenaccordela
permission.
K.Si unesectionDdicacesouunesectionRemerciementssont
prsentes, lesinforma
tionsetlesapprciationsconcernantlescontributeursetlespersonnesauxquellessadressentces
remerciementsdoiventtreconserves,ainsiqueletitredecessections.
L.ConserversansmodificationlesSectionsinaltrablesduDocument,nidansleurstextes,nidans
leurstitres. Lesnumrosdesectionsnesontpasconsidrscommefaisantpartiedutextedes
sections.
M.EffacertoutesectionintituleApprobations.Unetellesectionnepeutpastreinclusedans
uneVersionmodifie.
N.NepasrenommerunesectionexistantesousletitreApprobationsousousunautretitreentrant
enconflitavecletitreduneSectioninaltrable.
SilaVersionmodifiecontientdenouvellessectionsprliminairesoudenouvellesannexesconsid
rescommedesSectionssecondaires,etquecellescinecontiennentaucunlmentcopidepuisle
Document,vouspouvezvotreconvenanceendsigneruneouplusieurscommetantdesSections
inaltrables.Pourcefaire,ajoutezleurstitresdanslalistedesSectionsinaltrablesauseindelanotice
deLicencedelaVersionmodifie.Cestitresdoiventtresdistinctsdestitresdesautressections.
VouspouvezajouterunesectionnommeApprobations,
conditionquecesapprobationsne
concernentquelesmodificationsayantdonnnaissancelaVersionmodifie(parexemple,comptes
rendusderevuededocument,ouacceptationdutexteparuneorganisationlereconnaissantcomme
tantladfinitiondunstandard).
Vouspouvezajouterunpassagecomprenantjusqucinqmotsenpremirepagedecouverture, et
jusquvingtcinqmotsendernirepagedecouverture, lalistedesTextesdecouverturedela
Versionmodifie.Ilnestautorisdajouterquunseulpassageenpremireetendernirepagede
couvertureparpersonneougroupedepersonnesouorganisationayantcontribulamodificationdu
Document.SileDocumentcomportedjunpassagesurlammecouverture,ajoutenvotrenom
ouaunomdelorganisationaunomdelaquellevousagissez,vousnepouvezpasajouterdepassage
supplmentaire;maisvouspouvezremplacerunancienpassagesivousavezexpressmentobtenu
lautorisationdelditeurdeceluici.
CetteLicencenevousdonnepasledroitdutiliserlenomdesauteursetdesditeursdeceDocument
desfinspublicitairesoupourprtendrelapprobationduneVersionmodifie.
5FUSIONDEDOCUMENTS
442
AnnexeD.LicencededocumentationlibreGNU
VouspouvezfusionnerleDocument avecdautresdocumentssoumiscetteLicence, suivant les
spcificationsdelasection4pourlesVersionsmodifies, conditiondincluredansledocument
rsultanttouteslesSectionsinaltrablesdesdocumentsoriginauxsansmodification,etdetoutesles
listerdanslalistedesSectionsinaltrablesdelanoticedeLicencedudocumentrsultantdelafusion.
LedocumentrsultantdelafusionnabesoinqueduneseulecopiedecetteLicence,etlesSections
inaltrablesexistant enmultiplesexemplairespeuvent treremplacesparunecopieunique. Sil
existeplusieursSectionsinaltrablesportantlemmenommaisdecontenudiffrent,rendezunique
letitredechaquesectionenajoutant,lafindeceluici,entreparenthses,lenomdelauteuroude
lditeurdorigine,ou,dfaut,unnumrounique.Lesmmesmodificationsdoiventtreralises
danslalistedesSectionsinaltrablesdelanoticedeLicencedudocumentfinal.
Dans le document rsultant de la fusion, vous devez rassembler en une seule toutes les
sectionsHistoriquedesdocumentsdorigine.
Demme, vousdevezrassemblerlessections
RemerciementsetDdicaces.VousdevezsupprimertouteslessectionsApprobations.
6REGROUPEMENTSDEDOCUMENTS
VouspouvezcrerunregroupementdedocumentscomprenantleDocumentetdautresdocuments
soumiscetteLicence,etremplacerlescopiesindividuellesdecetteLicencedesdiffrentsdocuments
paruneuniquecopieinclusedansleregroupementdedocuments,conditionderespecterpourcha
cundecesdocumentslensembledesrglesdecetteLicenceconcernantlescopiesconformes.
Vouspouvezextraireundocumentduntelregroupement,etledistribuerindividuellementsouscou
vertdecetteLicence,conditiondyinclureunecopiedecetteLicenceetdelensembledesrgles
concernantlescopiesconformes.
7AGRGATIONAVECDESTRAVAUXINDPENDANTS
LacompilationduDocumentousesdrivsavecdautresdocumentsoutravauxsparsetindpen
dantssurunsupportdestockageousurunmdiadedistributionquelconquenereprsentepasune
VersionmodifieduDocumenttantquaucuncopyrightnestdpospourcettecompilation.Unetelle
compilationestappeleagrgat,etcetteLicencenesappliquepasauxautrestravauxindpen
dantscompilsavecleDocument,silsnesontpaseuxmmesdestravauxdrivsduDocument.
Silesexigencesdelasection3concernantlesTextesdecouverturesontapplicablescescopiesdu
Document,etsileDocumentreprsenteunvolumeinfrieurunquartduvolumetotaldelagrgat,
lesTextesdecouvertureduDocumentpeuventtreplacssurdespagesdecouverturequinencadrent
queleDocumentauseindelagrgat.Danslecascontraire,ilsdoiventapparatresurlespagesde
couverturedelagrgatcomplet.
8TRADUCTION
Latraductionestconsidrecommeuneformedemodification,vouspouvezdoncdistribuerlestra
ductionsduDocumentselonlestermesdelasection4.Vousdevezobtenirlautorisationspcialedes
auteursdesSectionsinaltrablespourlesremplacerpardestraductions,
maisvouspouvezinclure
lestraductionsdesSectionsinaltrablesenplusdestextesoriginaux. Vouspouvezinclureunetra
ductiondecetteLicenceconditiondincluregalementlaversionoriginaleenanglais.Encasde
contradictionentrelatraductionetlaversionoriginaleenanglais,cestcettedernirequiprvaut.
9RVOCATION
Vousnepouvezpascopier,modifier,souslicencieroudistribuerleDocumentautrementqueselon
lestermesdecetteLicence. Toutautreactedecopie, modification, souslicenceoudistributiondu
DocumentestsansobjetetvouspriveautomatiquementdesdroitsquecetteLicencevousaccorde.
Enrevanche,lespersonnesquiontreudevotrepartdescopiesoulesdroitssurledocumentsous
couvertdecetteLicencenevoientpasleursdroitscaducstantquellesenrespectentlesprincipes.
10RVISIONSFUTURESDECETTELICENCE
443
AnnexeD.LicencededocumentationlibreGNU
LaFreeSoftwareFoundationpeut publierdetempsentempsdenouvellesversionsrvisesde
cetteLicence. Cesnouvellesversionsseront semblableslaprsenteversiondanslesprit,
mais
pourrontdiffrersurdespointsdedtailenfonctiondenouvellesquestionsouproblmes.
Voyez
http://www.gnu.org/copyleft/pourplusdedtails.
ChaqueversiondecetteLicenceestdotedunnumrodeversiondistinct.SiunDocumentspcifieun
numrodeversionparticulierdecetteLicence,etportelamentionoutouteautreversionultrieure,
vouspouvezchoisirdesuivrelestermesdelaversionspcifieouceuxdenimportequelleversion
ultrieurepublieparlaFreeSoftwareFoundation.Siaucunnumrodeversionnestspcifi,vous
pouvezchoisirnimportequelleversionofficiellepublieparlaFreeSofwareFoundation.
444
BIBLIOGRAPHIE
LangageC
CasaSecondLanguageForNativeSpeakersofPascal,MldnerandSteele,AddisonWesley.
TheCProgrammingLanguage,BrianW.KernighamandDennisM.Ritchie,PrenticeHall.
LangageC++
LessentielduC++,StanleyB.Lippman,AddisonWesley.
TheC++ProgrammingLanguage,BjarneStroustrup,AddisonWesley.
WorkingPaperforDraftProposedInternationalStandardforInformationSystemsProgramming
LanguageC++(http://casteyde.christian.free.fr.cpp/cours/drafts/index.html),ISO.
BibliothqueC/appelssystmesPOSIXet
algorithmique
ProgrammationsystmeenCsousLinux,ChristopheBlaess,Eyrolles.
TheSingleUNIXSpecification, Version3(http://www.unixsystems.org/single_unix_specification/),
TheOpenGroup.
Introductionlalgorithmique,ThomasCormen,CharlesLeiserson,etRonaldRivest,Dunod.
445
BIBLIOGRAPHIE
446