A C++ Programozási nyelv 9789639301191 [PDF]

A könyv, amelyből több, mint félmillió programozó tanult... Kötetünk az ANS/ISO szabvány szerinti C++ nyelvet, annak sta

143 63 4MB

Hungarian Pages [1315] Year 2001

Report DMCA / Copyright

DOWNLOAD PDF FILE

Table of contents :
cpluszplusz_tartalom
C_Stroustrup
01.pdf
02.pdf
03.pdf
04.pdf
05.pdf
06.pdf
07.pdf
08.pdf
09.pdf
10.pdf
11.pdf
12.pdf
13.pdf
14.pdf
15.pdf
16.pdf
17.pdf
18.pdf
19.pdf
20.pdf
21.pdf
22.pdf
23.pdf
24.pdf
25.pdf
26.pdf
27.pdf
28.pdf
29.pdf
30.pdf
Papiere empfehlen

A C++ Programozási nyelv
 9789639301191 [PDF]

  • 0 0 0
  • Gefällt Ihnen dieses papier und der download? Sie können Ihre eigene PDF-Datei in wenigen Minuten kostenlos online veröffentlichen! Anmelden
Datei wird geladen, bitte warten...
Zitiervorschau

I. kötet

A kiadvány a következõ angol eredeti alapján készült: Bjarne Stroustrup: The C++ Programming Language Special Edition Copyright © 2000 by AT&T. All rights reserved. No part of this book, including interior desing, cover design, and icons, may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording, or otherwise) without the prior written permission of the publisher. Trademarked names appear throughout this book. Rather than list the names and entities that own the trademarks or insert a trademark symbol with each mention of the trademarked name, the publisher states that it is using the names for editorial purposes only and to the benefit of the trademark owner, with no intention of infringing upon that trademark. A szerzõ és a kiadó a lehetõ legnagyobb körültekintéssel járt el e kiadvány elkészítésekor. Sem a szerzõ, sem a kiadó nem vállal semminemû felelõsséget vagy garanciát a könyv tartalmával, teljességével kapcsolatban. Sem a szerzõ, sem a kiadó nem vonható felelõsségre bármilyen baleset vagy káresemény miatt, mely közvetve vagy közvetlenül kapcsolatba hozható e kiadvánnyal. Fordítás és magyar változat © 2001 Szy György, Kiskapu Kft. Minden jog fenntartva! Translation and Hungarian edition © 2001 György Szy, Kiskapu Kft. All rights reserved! Sorozatszerkesztõ: Szy György Mûszaki szerkesztõ: Csutak Hoffmann Levente Szakmai lektor: Porkoláb Zoltán Lektor: Rézmûves László Fordítók: Balázs Iván József, Bein Kornél, Ludányi Levente, Marcinkovics Tamás

Felelõs kiadó a Kiskapu Kft. ügyvezetõ igazgatója © 2001 Kiskapu Kft. 1081 Budapest Népszínház u. 31. Tel: (+36-1) 303-9119, (+36-1) 477-0443 Fax: (+36-1) 303-1619 http://www.kiskapu.hu/ e-mail: [email protected] Elsõ kötet ISBN: 963 9301 18 3 Összesítõ ISBN: 963 9301 17 5 ö Készült a debreceni Kinizsi nyomdában Felelõs vezetõ: Bördõs János

Tartalomjegyzék

Bevezetés 1. fejezet

Megjegyzések az olvasóhoz

1.1. A könyv szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

1.1.1. Példák és hivatkozások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.1.2. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.1.3. Megjegyzés az egyes C++-változatokhoz . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.2. Hogyan tanuljuk a C++-t? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.3. A C++ jellemzõi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1.3.1. Hatékonyság és szerkezet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3.2. Filozófiai megjegyzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

1.4. Történeti megjegyzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.5. A C++ használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.6. C és C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1.6.1. Javaslatok C programozóknak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 1.6.2. Javaslatok C++ programozóknak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

1.7. Programozási megfontolások a C++-ban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.8. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

1.8.1. Hivatkozások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2. fejezet

Kirándulás a C++-ban

2.1. Mi a C++? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.2. Programozási megközelítések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.3. Eljárásközpontú programozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.3.1. Változók és aritmetika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.3.2. Elágazások és ciklusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

x

2.3.3. Mutatók és tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

2.4. Moduláris programozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

2.4.1. Külön fordítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 2.4.2. Kivételkezelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

2.5. Elvont adatábrázolás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.5.1. 2.5.2. 2.5.3. 2.5.4. 2.5.5.

Típusokat leíró modulok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 Felhasználói típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Konkrét típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Absztrakt típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Virtuális függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

2.6. Objektumorientált programozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

2.6.1. Problémák a konkrét típusokkal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 2.6.2. Osztályhierarchiák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

2.7. Általánosított programozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

2.7.1. Tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 2.7.2. Általánosított algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

2.8. Utóirat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 2.9. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

3. fejezet

Kirándulás a standard könyvtárban

3.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.2. Helló, világ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 3.3. A standard könyvtár névtere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 3.4. Kimenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 3.5. Karakterláncok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

3.5.1.C stílusú karakterláncok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

3.6. Bemenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 3.7. Tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 3.7.1. 3.7.2. 3.7.3. 3.7.4. 3.7.5.

Vektor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Tartományellenõrzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Lista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 Asszociatív tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 Szabványos tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

3.8.1. 3.8.2. 3.8.3. 3.8.4. 3.8.5. 3.8.6.

Bejárók használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 Bejárótípusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 Bemeneti és kimeneti bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 Bejárások és predikátumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 Tagfüggvényeket használó algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . 81 A standard könyvtár algoritmusai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

3.8. Algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

3.9. Matematika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 3.9.1. Komplex számok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 3.9.2. Vektoraritmetika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 3.9.3. Alapszintû numerikus támogatás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

3.10. A standard könyvtár szolgáltatásai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 3.11. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

xi

Elsõ rész

Alapok

4. fejezet

Típusok és deklarációk

4.1. Típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 4.1.1. Alaptípusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

4.2. Logikai típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 4.3. Karaktertípusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.3.1. Karakterliterálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

4.4. Egész típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95

4.4.1. Egész literálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

4.5. Lebegõpontos típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

4.5.1. Lebegõpontos literálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

4.6. Méretek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 4.7. Void . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.8. Felsoroló típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.9. Deklarációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 4.9.1. 4.9.2. 4.9.3. 4.9.4. 4.9.5. 4.9.6. 4.9.7.

A deklarációk szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 Több név bevezetése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 Nevek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 Hatókörök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Kezdeti értékadás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 Objektumok és balértékek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Typedef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

4.10. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 4.11. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

5. fejezet

Mutatók, tömbök és struktúrák

5.1. Mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

5.1.1. Nulla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

5.2. Tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117

5.2.1. Tömbök feltöltése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 5.2.2. Karakterliterálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

5.3. Tömbökre hivatkozó mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

5.3.1. Tömbök bejárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

5.4. Konstansok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125

5.4.1. Mutatók és konstansok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

5.5. Referenciák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 5.6. Void-ra hivatkozó mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 5.7. Struktúrák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

5.7.1. Egyenértékû típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

5.8. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 5.9. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

xii

6. fejezet

Kifejezések és utasítások

6.1. Egy asztali számológép . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 6.1.1. 6.1.2. 6.1.3. 6.1.4. 6.1.5. 6.1.6. 6.1.7. 6.1.8.

Az elemzõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 A bemeneti függvény . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 Alacsonyszintû bemenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Hibakezelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 A vezérlõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Fejállományok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Parancssori paraméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Megjegyzés a stílussal kapcsolatban . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

6.2. Operátorok – áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158

6.2.1. Eredmények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 6.2.2. Kiértékelési sorrend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 6.2.3. Az operátorok sorrendje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 6.2.4. Bitenkénti logikai mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 6.2.5. Növelés és csökkentés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 6.2.6. Szabad tár . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 6.2.6.1. Tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 6.2.6.2. Memória-kimerülés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 6.2.7. Meghatározott típuskonverziók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 6.2.8. Konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

6.3. Utasítások – áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

6.3.1. Deklarációk mint utasítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 6.3.2. Kiválasztó utasítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 6.3.2.1. Deklarációk feltételekben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 6.3.3. Ciklusutasítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 6.3.3.1. Deklarációk a for utasításban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 6.3.4. Goto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

6.4. Megjegyzések és behúzás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 6.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 6.6. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187

7. fejezet

Függvények

7.1. Függvénydeklarációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191

7.1.1. Függvénydefiníciók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 7.1.2. Statikus változók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193

7.2. Paraméterátadás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194

7.2.1. Tömb paraméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196

7.3. Visszatérési érték . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 7.4. Túlterhelt függvénynevek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 7.4.1. 7.4.2. 7.4.3. 7.4.4.

A túlterhelés és a visszatérési típus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 A túlterhelés és a hatókör . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 A többértelmûség „kézi” feloldása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Több paraméter feloldása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

7.5. Alapértelmezett paraméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 7.6. Nem meghatározott számú paraméter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

xiii

7.7. Függvényre hivatkozó mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 7.8. Makrók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 7.8.1. Feltételes fordítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

7.9. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 7.10. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218

8. fejezet

Névterek és kivételek

8.1. Modulok és felületek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221 8.2. Névterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224

8.2.1. Minõsített nevek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 8.2.2. Using deklarációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 8.2.3. Using direktívák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 8.2.4. Több felület használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 8.2.4.1. Felülettervezési módszerek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 8.2.5. A névütközések elkerülése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 8.2.5.1. Névtelen névterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 8.2.6. Nevek keresése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237 8.2.7. Névtér-álnevek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 8.2.8. Névterek összefûzése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 8.2.8.1. Kiválasztás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 8.2.8.2. Összefûzés és kiválasztás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 8.2.9. Névterek és régi kódok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 8.2.9.1. Névterek és a C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 8.2.9.2. Névterek és túlterhelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 8.2.9.3. A névterek nyitottak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246

8.3. Kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248

8.3.1. „Dobás és elkapás” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 8.3.2. A kivételek megkülönböztetése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251 8.3.3. Kivételek a számológépben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 8.3.3.1. Más hibakezelõ módszerek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

8.4. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 8.5. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258

9. fejezet

Forrásfájlok és programok

9.1. Külön fordítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 9.2. Összeszerkesztés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

9.2.1. Fejállományok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 9.2.2. A standard könyvtár fejállományai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 9.2.3. Az egyszeri definiálás szabálya . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 9.2.4. Összeszerkesztés nem C++ kóddal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272 9.2.5. Az összeszerkesztés és a függvényekre hivatkozó mutatók . . . . . . . . . . . 275

9.3. Fejállományok használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

9.3.1. Egyetlen fejállományos elrendezés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 9.3.2. Több fejállományos elrendezés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 9.3.2.1. A számológép egyéb moduljai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282 9.3.2.2. A fejállományok használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285 9.3.3. „Állomány-õrszemek” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286

xiv

9.4. Programok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

9.4.1. Kezdeti értékadás nem lokális változóknak . . . . . . . . . . . . . . . . . . . . . . . . 288 9.4.1.1. A program befejezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289

9.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 9.6. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291

Második rész Absztrakciós módszerek 10. fejezet

Osztályok

10.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295 10.2. Osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296

10.2.1. Tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296 10.2.2. Az elérhetõség szabályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 10.2.3. Konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 10.2.4. Statikus tagok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 10.2.5. Osztály típusú objektumok másolása . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 10.2.6. Konstans tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 10.2.7. Önhivatkozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 10.2.7.1. Fizikai és logikai konstansok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306 10.2.7.2. A mutable minõsítõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 10.2.8. Struktúrák és osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 10.2.9. Osztályon belüli függvénydefiníciók . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310

10.3. Hatékony felhasználói típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 10.3.1. 10.3.2. 10.3.3. 10.3.4.

Tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 Segédfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 Operátorok túlterhelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 A konkrét osztályok jelentõsége . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319

10.4. Objektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320

10.4.1. Destruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 10.4.2. Alapértelmezett konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 10.4.3. Létrehozás és megsemmisítés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322 10.4.4. Lokális változók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 10.4.4.1. Objektumok másolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323 10.4.5. A szabad tár . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 10.4.6. Osztály típusú tagok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 10.4.6.1. A tagok szükségszerû kezdeti értékadása . . . . . . . . . . . . . . . . . . . . . . . . 327 10.4.6.2. Konstans tagok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328 10.4.6.3. Tagok másolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329 10.4.7. Tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330 10.4.8. Lokális statikus adatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 10.4.9. Nem lokális adatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332 10.4.10. Ideiglenes objektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 10.4.11. Az objektumok elhelyezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 10.4.12. Uniók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339

10.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 10.6. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340

xv

11. fejezet

Operátorok túlterhelése

11.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 11.2. Operátor függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 11.2.1. 11.2.2. 11.2.3. 11.2.4.

Egy- és kétoperandusú mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 Az operátorok elõre meghatározott jelentése . . . . . . . . . . . . . . . . . . . . . 347 Operátorok és felhasználói típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348 Névterek operátorai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

11.3.1. 11.3.2. 11.3.3. 11.3.4. 11.3.5. 11.3.6. 11.3.7. 11.3.8.

Tag és nem tag operátorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Vegyes módú aritmetika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 Kezdeti értékadás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Másolás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Konstruktorok és konverziók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Literálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Kiegészítõ tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359 Segédfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360

11.3. Komplex szám típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 351

11.4. Konverziós operátorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 11.4.1. Többértelmûség . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363

11.5. Barát függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366

11.5.1. A barát függvények elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 11.5.2. Barátok és tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369

11.6. Nagy objektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 11.7. Alapvetõ operátorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373

11.7.1. Explicit konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374

11.8. Indexelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 11.9. Függvényhívás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377 11.10. Indirekció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 11.11. Növelés és csökkentés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 382 11.12. Egy karakterlánc osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 384 11.13. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 11.14. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391

12. fejezet

Származtatott osztályok

12.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 12.2. Származtatott osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 12.2.1. 12.2.2. 12.2.3. 12.2.4. 12.2.5. 12.2.6.

Tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 Konstruktorok és destruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 Másolás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 Osztályhierarchiák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Típusmezõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405 Virtuális függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407

12.3. Absztrakt osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 12.4. Osztályhierarchiák tervezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413

12.4.1. Hagyományos osztályhierarchia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 12.4.1.1. Bírálat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417

xvi

12.4.2. Absztrakt osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418 12.4.3. Egyéb megvalósítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 12.4.3.1. Bírálat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423 12.4.4. Az objektumok létrehozásának adott helyre korlátozása . . . . . . . . . . . . . 424

12.5. Osztályhierarchiák és absztrakt osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 12.6. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 12.7. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427

13. fejezet

Sablonok

13.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431 13.2. Egy egyszerû karakterlánc sablon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 13.2.1. 13.2.2. 13.2.3. 13.2.4. 13.2.5.

Sablonok meghatározása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 Sablonok példányosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436 Sablon paraméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437 Típusok egyenértékûsége . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 Típusellenõrzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439

13.3. Függvénysablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440

13.3.1. A függvénysablonok paraméterei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 13.3.2. Függvénysablonok túlterhelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443

13.4. Eljárásmód megadása sablonparaméterekkel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446

13.4.1. Alapértelmezett sablonparaméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447

13.5. Specializáció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449

13.5.1. Specializációk sorrendje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 13.5.2. Függvénysablon specializáció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453

13.6. Öröklõdés és sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455

13.6.1. Paraméterezés és öröklõdés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457 13.6.2. Tag sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 457 13.6.3. Öröklõdési viszonyok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459 13.6.3.1. Sablonok konverziója . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 460

13.7. A forráskód szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 13.8. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 13.9. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465

14. fejezet

Kivételkezelés

14.1. Hibakezelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467

14.1.1. A kivételek más megközelítései . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470

14.2. A kivételek csoportosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471

14.2.1. Származtatott kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 14.2.2. Összetett kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

14.3. A kivételek elkapása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475

14.3.1. A kivételek továbbdobása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 14.3.2. Minden kivétel elkapása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 14.3.2.1. A kezelõk sorrendje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478

14.4. Erõforrások kezelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479

14.4.1. Konstruktorok és destruktorok használata . . . . . . . . . . . . . . . . . . . . . . . 481 14.4.2. Auto_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483

xvii

14.4.3. Figyelmeztetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 14.4.4. A kivételek és a new operátor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 14.4.5. Az erõforrások kimerülése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486 14.4.6. Kivételek konstruktorokban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 14.4.6.1. Kivételek és a tagok kezdeti értékadása . . . . . . . . . . . . . . . . . . . . . . . . . 490 14.4.6.2. Kivételek és másolás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491 14.4.7. Kivételek destruktorokban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491

14.5. Kivételek, amelyek nem hibák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492 14.6. Kivételek specifikációja . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493

14.6.1. A kivételek ellenõrzése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494 14.6.2. Váratlan kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496 14.6.3. Kivételek leképezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 14.6.3.1. Kivételek felhasználói leképezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 14.6.3.2. Kivételek típusának visszaállítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499

14.7. El nem kapott kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499 14.8. A kivételek és a hatékonyság . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 14.9. A hibakezelés egyéb módjai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 503 14.10. Szabványos kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 14.11. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508 14.12. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509

15. fejezet

Osztályhierarchiák

15.1. Bevezetés és áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 511 15.2. Többszörös öröklõdés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512

15.2.1. A többértelmûség feloldása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 15.2.2. Öröklõdés és using deklarációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515 15.2.3. Ismétlõdõ bázisosztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 15.2.3.1. Felülírás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518 15.2.4. Virtuális bázisosztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 15.2.4.1. Virtuális bázisosztályok programozása . . . . . . . . . . . . . . . . . . . . . . . . . . 521 15.2.5. A többszörös öröklõdés használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 15.2.5.1. A virtuális bázisosztályok függvényeinek felülírása . . . . . . . . . . . . . . . . 526

15.3. Hozzáférés-szabályozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528

15.3.1. Védett tagok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530 15.3.1.1. A védett tagok használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 15.3.2. Bázisosztályok elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532 15.3.2.1. A többszörös öröklõdés és az elérhetõség . . . . . . . . . . . . . . . . . . . . . . . 533 15.3.2.2. A using deklarációk és az elérhetõség . . . . . . . . . . . . . . . . . . . . . . . . . . 534

15.4. Futási idejû típusinformáció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535

15.4.1. Dynamic_cast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536 15.4.1.1. Referenciák dinamikus típuskényszerítése . . . . . . . . . . . . . . . . . . . . . . . 539 15.4.2. Osztályhierarchiák bejárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 15.4.2.1. Statikus és dinamikus konverzió . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542 15.4.3. Osztályobjektumok felépítése és megsemmisítése . . . . . . . . . . . . . . . . 543

xviii

15.4.4. Typeid és kiterjesztett típusinformáció . . . . . . . . . . . . . . . . . . . . . . . . . . 544 15.4.4.1. Kiterjesztett típusinformáció . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546 15.4.5. Az RTTI helyes és helytelen használata . . . . . . . . . . . . . . . . . . . . . . . . . 547

15.5. Tagra hivatkozó mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549

15.5.1. Bázis- és származtatott osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552

15.6. A szabad tár . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553

15.6.1. Memóriafoglalás tömbök számára . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556 15.6.2. „Virtuális konstruktorok” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 556

15.7. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558 15.8. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559

II. kötet

A kiadvány a következõ angol eredeti alapján készült: Bjarne Stroustrup: The C++ Programming Language Special Edition Copyright © 2000 by AT&T. All rights reserved. No part of this book, including interior desing, cover design, and icons, may be reproduced or transmitted in any form, by any means (electronic, photocopying, recording, or otherwise) without the prior written permission of the publisher. Trademarked names appear throughout this book. Rather than list the names and entities that own the trademarks or insert a trademark symbol with each mention of the trademarked name, the publisher states that it is using the names for editorial purposes only and to the benefit of the trademark owner, with no intention of infringing upon that trademark. A szerzõ és a kiadó a lehetõ legnagyobb körültekintéssel járt el e kiadvány elkészítésekor. Sem a szerzõ, sem a kiadó nem vállal semminemû felelõsséget vagy garanciát a könyv tartalmával, teljességével kapcsolatban. Sem a szerzõ, sem a kiadó nem vonható felelõsségre bármilyen baleset vagy káresemény miatt, mely közvetve vagy közvetlenül kapcsolatba hozható e kiadvánnyal. Fordítás és magyar változat © 2001 Szy György, Kiskapu Kft. Minden jog fenntartva! Translation and Hungarian edition © 2001 György Szy, Kiskapu Kft. All rights reserved! Sorozatszerkesztõ: Szy György Mûszaki szerkesztõ: Csutak Hoffmann Levente Szakmai lektor: Porkoláb Zoltán Lektor: Rézmûves László Fordítók: Balázs Iván József, Bein Kornél, Ludányi Levente, Marcinkovics Tamás

Felelõs kiadó a Kiskapu Kft. ügyvezetõ igazgatója © 2001 Kiskapu Kft. 1081 Budapest Népszínház u. 31. Tel: (+36-1) 303-9119, (+36-1) 477-0443 Fax: (+36-1) 303-1619 http://www.kiskapu.hu/ e-mail: [email protected] Második kötet ISBN: 963 9301 19 1 Összesítõ ISBN: 963 9301 17 5 ö Készült a debreceni Kinizsi nyomdában Felelõs vezetõ: Bördõs János

A könyv az Oktatási Minisztérium támogatásával, a Felsõoktatási Pályázatok Irodája által lebonyolított felsõoktatási tankönyvtámogatási program keretében jelent meg.

Tartalomjegyzék Harmadik rész

A standard könyvtár

16. fejezet A könyvtár szerkezete és a tárolók 16.1. A standard könyvtár . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563

16.1.1. Tervezési korlátozások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 565 16.1.2. A standard könyvtár szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 566 16.1.3. Nyelvi elemek támogatása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571

16.2. A tárolók szerkezete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572

16.2.1. Egyedi célú tárolók és bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572 16.2.2. Tárolók közös õssel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576 16.2.3. A standard könyvtár tárolói . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581

16.3. A vektor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 16.3.1. Típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 16.3.2. Bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585 16.3.3. Az elemek elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 16.3.4. Konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589 16.3.5. Veremmûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593 16.3.6. Listamûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595 16.3.7. Az elemek kiválasztása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599 16.3.8. Méret és kapacitás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600 16.3.9. További tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 16.3.10. Segédfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603 16.3.11. Vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 604

16.4. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605 16.5. Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606 17. fejezet Szabványos tárolók 17.1. A szabványos tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 609

17.1.1. Mûveletek – áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 610 17.1.2. Tárolók – áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615 17.1.3. Ábrázolás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616 17.1.4. Megkötések az elemekre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618 17.1.4.1. Összehasonlítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619 17.1.4.2. További relációs mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 621

viii

17.2. Sorozatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622

17.2.1. A vector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622 17.2.2. A list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 17.2.2.1. Áthelyezés, rendezés, összefésülés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623 17.2.2.2. Mûveletek a lista elején . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626 17.2.2.3. További mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626 17.2.3. A deque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629

17.3. Sorozat-átalakítók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629

17.3.1. A stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630 17.3.2. A queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 632 17.3.3. A priority_queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633

17.4. Asszociatív tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 636

17.4.1. A map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 17.4.1.1. Típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 17.4.1.2. Bejárók és párok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638 17.4.1.3. Indexelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 640 17.4.1.4. Konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642 17.4.1.5. Összehasonlítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642 17.4.1.6. Mûveletek asszociatív tömbökkel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644 17.4.1.7. Listamûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 646 17.4.1.8. További mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648 17.4.2. A multimap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649 17.4.3. A set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650 17.4.4. A multiset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651

17.5. Majdnem-tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652

17.5.1. Karakterláncok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 17.5.2. A valarray . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 17.5.3. Bithalmazok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 17.5.3.1. Konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 654 17.5.3.2. Bitkezelõ mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655 17.5.3.3. További mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 656 17.5.4. Beépített tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 657

17.6. Új tárolók létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659

17.6.1. A hash_map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659 17.6.2. Ábrázolás és létrehozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661 17.6.2.1. Keresések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 663 17.6.2.2. Törlés és átméretezés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 665 17.6.2.3. Hasítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 666 17.6.3. További hasított asszociatív tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668

17.7. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668 17.8. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669 18. fejezet Algoritmusok és függvényobjektumok 18.1. Bevezetõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673 18.2. A standard könyvtár algoritmusainak áttekintése . . . . . . . . . . . . . . . . . . . . . . . . . . 674 18.3. Sorozatok és tárolók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681

18.3.1. Bemeneti sorozatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 682

18.4. Függvényobjektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 684

ix

18.4.1. Függvényobjektumok bázisosztályai . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685 18.4.2. Predikátumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 686 18.4.2.1. A predikátumok áttekintése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 687 18.4.3. Aritmetikai függvényobjektumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688 18.4.4. Lekötõk, átalakítók és tagadók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689 18.4.4.1. Lekötõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691 18.4.4.2. Tagfüggvény-átalakítók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 693 18.4.4.3. Függvényre hivatkozó mutatók átalakítói . . . . . . . . . . . . . . . . . . . . . . . . 694 18.4.4.4. Tagadók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695

18.5. Nem módosító algoritmusok sorozatokon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697 18.5.1. 18.5.2. 18.5.3. 18.5.4. 18.5.5.

A for_each . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697 A find függvénycsalád . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 699 A count() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 700 Egyenlõség és eltérés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701 Keresés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703

18.6. Módosító algoritmusok sorozatokra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704

18.6.1. Másolás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 705 18.6.2. Transzformációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 707 18.6.3. Ismétlõdõ elemek törlése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709 18.6.3.1. Rendezési szempont . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711 18.6.4. Helyettesítés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712 18.6.5. Törlés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714 18.6.6. Feltöltés és létrehozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714 18.6.7. Megfordítás és elforgatás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715 18.6.8. Elemek felcserélése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717

18.7. Rendezett sorozatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717 18.7.1. 18.7.2. 18.7.3. 18.7.4. 18.7.5.

Rendezés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718 Bináris keresés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719 Összefésülés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 Felosztás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 Halmazmûveletek sorozatokon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 722

18.8. A kupac . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724 18.9. Minimum és maximum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725 18.10. Permutációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 726 18.11. C stílusú algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727 18.12. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728 18.13. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729 19. fejezet Bejárók és memóriafoglalók 19.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734 19.2. Bejárók és sorozatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 734

19.2.1. A bejárók mûveletei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 735 19.2.2. A bejáró jellemzõi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737 19.2.3. Bejáró-kategóriák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739 19.2.4. Beszúró bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742 19.2.5. Visszafelé haladó bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744 19.2.6. Adatfolyamok bejárói . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 19.2.6.1. Átmeneti tárak adatfolyamokhoz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748

x

19.3. Ellenõrzött bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750

19.3.1. Kivételek, tárolók és algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756

19.4. Memóriafoglalók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758 19.4.1. 19.4.2. 19.4.3. 19.4.4. 19.4.5. 19.4.6.

A szabványos memóriafoglaló . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758 Felhasználói memóriafoglalók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 763 Általánosított memóriafoglalók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 766 Elõkészítetlen memória . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 768 Dinamikus memória . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771 C stílusú helyfoglalás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772

19.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 773 19.6. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774 20. fejezet Karakterláncok 20.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 775 20.2. Karakterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 776 20.2.1. Karakterjellemzõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777

20.3. A basic_string osztály . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 780

20.3.1. Típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781 20.3.2. Bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 782 20.3.3. Az elemek elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 783 20.3.4. Konstruktorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784 20.3.5. Hibák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786 20.3.6. Értékadás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 788 20.3.7. Átalakítás C stílusú karakterláncra . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789 20.3.8. Összehasonlítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 791 20.3.9. Beszúrás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 793 20.3.10. Összefûzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 795 20.3.11. Keresés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 796 20.3.12. Csere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797 20.3.13. Részláncok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 799 20.3.14. Méret és kapacitás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801 20.3.15. Ki- és bemeneti mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801 20.3.16. Felcserélés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 802

20.4. A C standard könyvtára . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 802

20.4.1. C stílusú karakterláncok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 803 20.4.2. Karakterek osztályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805

20.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 806 20.6. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 807

21. fejezet Adatfolyamok 21.1. Bevezetõ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811 21.2. Kimenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814

21.2.1. Kimeneti adatfolyamok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 816 21.2.2. Beépített típusok kimenete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 818 21.2.3. Felhasználói típusok kimenete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821 21.2.3.1. Virtuális kimeneti függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 822

21.3. Bemenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823

21.3.1. Bemeneti adatfolyamok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 21.3.2. Beépített típusok bemenete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824

xi

21.3.3. 21.3.4. 21.3.5. 21.3.6. 21.3.7. 21.3.8.

Az adatfolyam állapota . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827 Karakterek beolvasása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829 Felhasználói típusok beolvasása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833 Kivételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834 Adatfolyamok összekötése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 836 Õrszemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838

21.4. Formázás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839

21.4.1. Formázási állapot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 840 21.4.1.1. Formázási állapot lemásolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842 21.4.2. Egész kimenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 842 21.4.3. Lebegõpontos szám kimenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843 21.4.4. Kimeneti mezõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845 21.4.5. Mezõk igazítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847 21.4.6. Módosítók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848 21.4.6.1. Módosítók, melyek paramétereket várnak . . . . . . . . . . . . . . . . . . . . . . . 850 21.4.6.2. Szabványos ki- és bemeneti módosítók . . . . . . . . . . . . . . . . . . . . . . . . . 851 21.4.6.3. Felhasználói módosítók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 853

21.5. Fájl- és karakterlánc-folyamok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855

21.5.1. Fájlfolyamok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856 21.5.2. Adatfolyamok lezárása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 859 21.5.3. Karakterlánc-folyamok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860

21.6. Ki- és bemeneti átmeneti tárak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 862 21.6.1. 21.6.2. 21.6.3. 21.6.4.

Kimeneti adatfolyamok és átmeneti tárolók . . . . . . . . . . . . . . . . . . . . . . 863 Bemeneti adatfolyamok és átmeneti tárolók . . . . . . . . . . . . . . . . . . . . . 865 Az adatfolyamok és az átmeneti tárak kapcsolata . . . . . . . . . . . . . . . . . . 866 Adatfolyamok átmeneti tárolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867

21.7. Helyi sajátosságok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 873

21.7.1. Adatfolyam-visszahívások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875

21.8. C stílusú ki- és bemenet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 876 21.9. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 880 21.10. Feladatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 881 22. fejezet Számok 22.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 886 22.2. A számtípusok korlátozásai . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 886 22.2.1. Korlátozási makrók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 890

22.3. Szabványos matematikai függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 890 22.4. Vektormûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892

22.4.1. Valarray létrehozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893 22.4.2. A valarray indexelése és az értékadás . . . . . . . . . . . . . . . . . . . . . . . . . . 894 22.4.3. Mûveletek tagfüggvényként . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 896 22.4.4. Nem tagfüggvényként megvalósított mûveletek . . . . . . . . . . . . . . . . . . . 900 22.4.5. Szeletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901 22.4.6. A slice_array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904 22.4.7. Ideiglenes változók, másolás, ciklusok . . . . . . . . . . . . . . . . . . . . . . . . . . 909 22.4.8. Általánosított szeletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 912 22.4.9. Maszkok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 914 22.4.10. Indirekt tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 915

22.5. Komplex aritmetika . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 915

xii

22.6. Általánosított numerikus algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 918

22.6.1. Az accumulate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 919 22.6.2. Az inner_product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 920 22.6.3. Növekményes változás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 921

22.7. Véletlenszámok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 923 22.8. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925 22.9. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 926

Negyedik rész

Tervezés a C++ segítségével

23.fejezet Fejlesztés és tervezés 23.1. Áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931 23.2. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932 23.3. Célok és eszközök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935 23.4. A fejlesztési folyamat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 939

23.4.1. A fejlesztés körforgása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 941 23.4.2. Tervezési célok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944 23.4.3. Tervezési lépések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 946 23.4.3.1. Elsõ lépés: keressünk osztályokat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 947 23.4.3.2. Második lépés: határozzuk meg a mûveleteket . . . . . . . . . . . . . . . . . . . 951 23.4.3.3. Harmadik lépés: határozzuk meg az összefüggéseket . . . . . . . . . . . . . . 953 23.4.3.4. Negyedik lépés: határozzuk meg a felületeket . . . . . . . . . . . . . . . . . . . . 953 23.4.3.5. Osztályhierarchiák újraszervezése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 954 23.4.3.6. Modellek használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 956 23.4.4. Kísérletezés és elemzés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 957 23.4.5. Tesztelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960 23.4.6. A programok „karbantartása” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961 23.4.7. Hatékonyság . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962

23.5. Vezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 963 23.5.1. 23.5.2. 23.5.3. 23.5.4.

Újrahasznosítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 963 Méret és egyensúly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 965 Egyének . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967 Hibrid tervezés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 969

24.2.1. 24.2.2. 24.2.3. 24.2.4. 24.2.5.

Az osztályok figyelmen kívül hagyása . . . . . . . . . . . . . . . . . . . . . . . . . . . 978 Az öröklés elkerülése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 981 A statikus típusellenorzés figyelmen kívül hagyása . . . . . . . . . . . . . . . . . 982 A programozás elkerülése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 985 Az osztályhierarchiák kizárólagos használata . . . . . . . . . . . . . . . . . . . . . 987

23.6. Jegyzetek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 971 23.7. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 973 24. fejezet Tervezés és programozás 24.1. Áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 975 24.2. A tervezés és a programozási nyelv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 976

24.3. Osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 988

24.3.1. Mit ábrázolnak az osztályok? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 989 24.3.2. Osztályhierarchiák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 991 24.3.2.1. Osztályhierarchián belüli függések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 994 24.3.3. Tartalmazási kapcsolatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996

xiii

24.3.4. Tartalmazás és öröklés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998 24.3.4.1. Tag vagy hierarchia? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1002 24.3.4.2. Tartalmazás vagy hierarchia? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1003 24.3.5. Használati kapcsolatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1005 24.3.6. Beprogramozott kapcsolatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1006 24.3.7. Osztályon belüli kapcsolatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1008 24.3.7.1. Invariánsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1009 24.3.7.2. Feltételezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1011 24.3.7.3. Elõfeltételek és utófeltételek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1015 24.3.7.4. Betokozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1016

24.4. Komponensek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1017

24.4.1. Sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1020 24.4.2. Felület és megvalósítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1022 24.4.3. Kövér felületek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1025

24.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1028 25. fejezet Az osztályok szerepe 25.1. Az osztályok fajtái . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1031 25.2. Konkrét típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1032

25.2.1. A konkrét típusok újrahasznosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1035

25.3. Absztrakt típusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1037 25.4. Csomópont-osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1041

25.4.1. Felületek módosítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1044

25.5. Mûveletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1047 25.6. Felületosztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1049 25.6.1. Felületek igazítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1051

25.7. Leíró osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1054

25.7.1. A leírók mûveletei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058

25.8. Keretrendszerek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1059 25.9. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1061 25.10. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1062

Függelékek és tárgymutató A. függelék Nyelvtan A.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1067 A.2. Kulcsszavak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1068 A.3. Lexikai szabályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1069 A.4. Programok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1073 A.5. Kifejezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1074 A.6. Utasítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1079 A.7. Deklarációk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1080 A.7.1. Deklarátorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1084

A.8. Osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1086

A.8.1. Származtatott osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1087 A.8.2. Különleges tagfüggvények . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1088 A.8.3. Túlterhelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1089

A.9. Sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1089

xiv

A.10. Kivételkezelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1091 A.11. Az elõfeldolgozó direktívái . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1091 B. függelék Kompatibilitás B.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1095 B.2. C/C++ kompatibilitás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1096

B.2.2. C program, ami nem C++ program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1097 B.2.3. Elavult szolgáltatások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1101 B.2.4. C++ program, ami nem C program . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1102

B.3. Régebbi C++-változatok használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1103 B.3.1. B.3.2. B.3.3. B.3.4. B.3.5. B.3.6.

Fejállományok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1104 A standard könyvtár . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1106 Névterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1107 Helyfoglalási hibák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1107 Sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1108 A for utasítás kezdõérték-adó része . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1110

C.3.1. C.3.2. C.3.3. C.3.4.

Korlátozott karakterkészletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1118 Escape karakterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1120 Nagy karakterkészletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1121 Elõjeles és elõjel nélküli karakterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1122

B.4. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1111 B.5. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1112 C. függelék Technikai részletek C.1. Bevezetés és áttekintés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1115 C.2. A szabvány . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1116 C.3. Karakterkészletek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1118

C.4. Az egész literálok típusa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1123 C.5. Konstans kifejezések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1124 C.6. Automatikus típuskonverzió . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1124

C.6.1. Kiterjesztések . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1124 C.6.2. Konverziók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1125 C.6.3. Szokásos aritmetikai konverziók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1129

C.7. Többdimenziós tömbök . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1129

C.7.1. Vektorok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1130 C.7.3. Többdimenziós tömbök átadása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1133

C.8. Ha kevés a memória… . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1135

C.8.1. Mezõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1135 C.8.2. Uniók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1136

C.9. Memóriakezelés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1139 C.9.1. Automatikus szemétgyûjtés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1140

C.10. Névterek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1144

C.10.1. Kényelem és biztonság . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1144 C.10.2. Névterek egymásba ágyazása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1146 C.10.3. Névterek és osztályok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1147

C.11. Hozzáférés-szabályozás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1147

C.11.1. Tagok elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1147 C.11.2. Bázisosztályok elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1148 C.11.3. Tagosztályok elérése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1150

xv

C.11.4. Barátok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1151

C.12. Adattagokra hivatkozó mutatók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1152 C.13. Sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1153

C.13.1. Statikus tagok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1153 C.13.2. Barátok és sablonok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1154 C.13.3. Sablonok, mint sablonparaméterek . . . . . . . . . . . . . . . . . . . . . . . . . . . 1155 C.13.4. Sablon függvények paramétereinek levezetése . . . . . . . . . . . . . . . . . . 1156 C.13.5. A typename és a template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1157 C.13.6. Sablonok, mint minõsítõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1159 C.13.7. Példányosítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1159 C.13.8. Névkötés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1160 C.13.9. Mikor van szükség specializációra? . . . . . . . . . . . . . . . . . . . . . . . . . . . 1169 C.13.10. Explicit példányosítás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1170

C.14. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1171 D. függelék Helyi sajátosságok D.1. A kulturális eltérések kezelése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1173

D.1.1. A kulturális eltérések programozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1174

D.2. A locale osztály . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1178 D.2.1. D.2.2. D.2.3. D.2.4.

Nevesített lokálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1181 Lokálok másolása és összehasonlítása . . . . . . . . . . . . . . . . . . . . . . . . . 1185 A global() és classic() lokálok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1187 Karakterláncok összehasonlítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1188

D.3. Jellemzõk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1189

D.3.1. Jellemzõk elérése a lokálokban . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1191 D.3.2. Egyszerû felhasználói facet-ek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1192 D.3.3. A lokálok és jellemzõk használata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1196

D.4. Szabványos facet-ek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1197 D.4.1. D.4.2. D.4.3. D.4.4. D.4.5. D.4.6. D.4.7.

Karakterláncok összehasonlítása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1200 Számok be- és kivitele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1205 Pénzértékek be- és kivitele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1212 Dátum és idõ beolvasása és kiírása . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1220 Karakterek osztályozása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1240 Karakterkód-átalakítások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1246 Üzenetek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1251

D.5. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1255 D.6. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1256 E. függelék Kivételbiztosság a standard könyvtárban E.1. Bevezetés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1259 E.2. Kivételbiztosság . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1261 E.3. A kivételbiztosságot megvalósító eljárások . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1266

E.3.1. Egy egyszerû vektor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1267 E.3.2. A memória ábrázolása . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1271 E.3.3. Értékadás . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1273 E.3.4. A push_back() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1276 E.3.5. Konstruktorok és invariánsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1278

E.4. A szabványos tárolók garanciái . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1284

E.4.1. Elemek beszúrása és törlése . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1286

xvi

E.4.2. E.4.3. E.4.4. E.4.5. E.4.6.

Garanciák és kompromisszumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1290 A swap() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1293 A kezdeti értékadás és a bejárók . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1294 Hivatkozások elemekre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1294 Predikátumok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1296

E.5. A standard könyvtár további részei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1296

E.5.1. Karakterláncok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1297 E.5.2. Adatfolyamok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1297 E.5.3. Algoritmusok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1298 E.5.4. A valarray és a complex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1299 E.5.5. A C standard könyvtára . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1299

E.6. Javaslatok a könyvtár felhasználói számára . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1300 E.7. Tanácsok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1303 E.8. Gyakorlatok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1304 I.

Tárgymutató

1307

Bevezetés

Ez a bevezetés áttekintést ad a C++ programozási nyelv fõ fogalmairól, tulajdonságairól és standard (szabvány) könyvtáráról, valamint bemutatja a könyv szerkezetét és elmagyarázza azt a megközelítést, amelyet a nyelv lehetõségeinek és azok használatának leírásánál alkalmaztunk. Ezenkívül a bevezetõ fejezetek némi háttérinformációt is adnak a C++-ról, annak felépítésérõl és felhasználásáról.

Fejezetek 1. Megjegyzések az olvasóhoz 2. Kirándulás a C++-ban 3. Kirándulás a standard könyvtárban

1 Megjegyzések az olvasóhoz

„Szólt a Rozmár: Van ám elég, mirõl mesélni jó: ...” (L. Carroll – ford. Tótfalusi István)

A könyv szerkezete • Hogyan tanuljuk a C++-t? • A C++ jellemzõi • Hatékonyság és szerkezet • Filozófiai megjegyzés • Történeti megjegyzés • Mire használjuk a C++-t? • C és C++ • Javaslatok C programozóknak • Gondolatok a C++ programozásról • Tanácsok • Hivatkozások

1.1. A könyv szerkezete A könyv hat részbõl áll: Bevezetés: Elsõ rész: Második rész:

Az 1–3. fejezetek áttekintik a C++ nyelvet, az általa támogatott fõ programozási stílusokat, és a C++ standard könyvtárát. A 4–9. fejezetek oktató jellegû bevezetést adnak a C++ beépített típusairól és az alapszolgáltatásokról, melyekkel ezekbõl programot építhetünk. A 10–15. fejezetek bevezetést adnak az objektumorientált és az általánosított programozásba a C++ használatával.

4

Bevezetés

Harmadik rész: A 16–22. fejezetek bemutatják a C++ standard könyvtárát. Negyedik rész: A 23–25. fejezetek tervezési és szoftverfejlesztési kérdéseket tárgyalnak. Függelékek: Az A–E függelékek a nyelv technikai részleteit tartalmazzák. Az 1. fejezet áttekintést ad a könyvrõl, néhány ötletet ad, hogyan használjuk, valamint háttérinformációkat szolgáltat a C++-ról és annak használatáról. Az olvasó bátran átfuthat rajta, elolvashatja, ami érdekesnek látszik, és visszatérhet ide, miután a könyv más részeit elolvasta. A 2. és 3. fejezet áttekinti a C++ programozási nyelv és a standard könyvtár fõ fogalmait és nyelvi alaptulajdonságait, megmutatva, mit lehet kifejezni a teljes C++ nyelvvel. Ha semmi mást nem tesznek, e fejezetek meg kell gyõzzék az olvasót, hogy a C++ nem (csupán) C, és hogy a C++ hosszú utat tett meg e könyv elsõ és második kiadása óta. A 2. fejezet magas szinten ismertet meg a C++-szal. A figyelmet azokra a nyelvi tulajdonságokra irányítja, melyek támogatják az elvont adatábrázolást, illetve az objektumorientált és az általánosított programozást. A 3. fejezet a standard könyvtár alapelveibe és fõ szolgáltatásaiba vezet be, ami lehetõvé teszi, hogy a szerzõ a standard könyvtár szolgáltatásait használhassa a következõ fejezetekben, valamint az olvasónak is lehetõséget ad, hogy könyvtári szolgáltatásokat használjon a gyakorlatokhoz és ne kelljen közvetlenül a beépített, alacsony szintû tulajdonságokra hagyatkoznia. A bevezetõ fejezetek egy, a könyv folyamán általánosan használt eljárás példáját adják: ahhoz, hogy egy módszert vagy tulajdonságot még közvetlenebb és valószerûbb módon vizsgálhassunk, alkalmanként elõször röviden bemutatunk egy fogalmat, majd késõbb behatóbban tárgyaljuk azt. Ez a megközelítés lehetõvé teszi, hogy konkrét példákat mutassunk be, mielõtt egy témát általánosabban tárgyalnánk. A könyv felépítése így tükrözi azt a megfigyelést, hogy rendszerint úgy tanulunk a legjobban, ha a konkréttól haladunk az elvont felé – még ott is, ahol visszatekintve az elvont egyszerûnek és magától értetõdõnek látszik. Az I. rész a C++-nak azt a részhalmazát írja le, mely a C-ben vagy a Pascalban követett hagyományos programozási stílusokat támogatja. Tárgyalja a C++ programokban szereplõ alapvetõ típusokat, kifejezéseket, vezérlési szerkezeteket. A modularitást, mint a névterek, forrásfájlok és a kivételkezelés által támogatott tulajdonságot, szintén tárgyalja. Feltételezzük, hogy az olvasónak már ismerõsek az I. fejezetben használt alapvetõ programozási fogalmak, így például bemutatjuk a C++ lehetõségeit a rekurzió és iteráció kifejezésére, de nem sokáig magyarázzuk, milyen hasznosak ezek. A II. rész a C++ új típusok létrehozását és használatát segítõ szolgáltatásait írja le. Itt (10. és 12. fejezet) mutatjuk be a konkrét és absztrakt osztályokat (felületeket), az operátor-túlterheléssel (11. fejezet), a többalakúsággal (polimorfizmussal) és az osztályhierarchiák hasz-

1. Megjegyzések az olvasóhoz

5

nálatával (12. és 15. fejezet) együtt. A 13. fejezet a sablonokat (template) mutatja be, vagyis a C++ lehetõségeit a típus- és függvénycsaládok létrehozására, valamint szemlélteti a tárolók elõállítására (pl. listák), valamint az általánosított (generikus) programozás támogatására használt alapvetõ eljárásokat. A 14. fejezet a kivételkezelést, a hibakezelési módszereket tárgyalja és a hibatûrés biztosításához ad irányelveket. Feltételezzük, hogy az olvasó az objektumorientált és az általánosított programozást nem ismeri jól, illetve hasznát látná egy magyarázatnak, hogyan támogatja a C++ a fõ elvonatkoztatási (absztrakciós) eljárásokat. Így tehát nemcsak bemutatjuk az elvonatkoztatási módszereket támogató nyelvi tulajdonságokat, hanem magukat az eljárásokat is elmagyarázzuk. A IV. rész ebben az irányban halad tovább. A III. rész a C++ standard könyvtárát mutatja be. Célja: megértetni, hogyan használjuk a könyvtárat; általános tervezési és programozási módszereket szemléltetni és megmutatni, hogyan bõvítsük a könyvtárat. A könyvtár gondoskodik tárolókról (konténerek – list, vector, map, 18. és 19. fejezet), szabványos algoritmusokról (sort, find, merge, 18. és 19. fejezet), karakterlánc-típusokról és -mûveletekrõl (20. fejezet), a bemenet és kimenet kezelésérõl (input/output, 21. fejezet), valamint a számokkal végzett mûveletek („numerikus számítás”) támogatásáról (22. fejezet). A IV. rész olyan kérdéseket vizsgál, melyek akkor merülnek fel, amikor nagy szoftverrendszerek tervezésénél és kivitelezésénél a C++-t használjuk. A 23. fejezet tervezési és vezetési kérdésekkel foglalkozik. A 24. fejezet a C++ programozási nyelv és a tervezési kérdések kapcsolatát vizsgálja, míg a 25. fejezet az osztályok használatát mutatja be a tervezésben. Az „A” függelék a C++ nyelvtana, néhány jegyzettel. A „B” függelék a C és a C++ közti és a szabványos C++ (más néven ISO C++, ANSI C++) illetve az azt megelõzõ C++-változatok közti rokonságot vizsgálja. A „C” függelék néhány nyelvtechnikai példát mutat be, A „D” függelék pedig a kulturális eltérések kezelését támogató standard könyvtárbeli elemeket mutatja be. Az „E” függelék a standard könyvtár kivételkezelésel kapcsolatos garanciáit és követelményeit tárgyalja.

1.1.1. Példák és hivatkozások Könyvünk az algoritmusok írása helyett a program felépítésére fekteti a hangsúlyt. Következésképpen elkerüli a ravasz vagy nehezebben érthetõ algoritmusokat. Egy egyszerû eljárás alkalmasabb az egyes fogalmak vagy a programszerkezet egy szempontjának szemléltetésére. Például Shell rendezést használ, ahol a valódi kódban jobb lenne gyorsrendezést (quicksort) használni. Gyakran jó gyakorlat lehet a kód újraírása egy alkalmasabb algoritmussal. A valódi kódban általában jobb egy könyvtári függvény hívása, mint a könyvben használt, a nyelvi tulajdonságok szemléltetésére használt kód.

6

Bevezetés

A tankönyvi példák szükségszerûen egyoldalú képet adnak a programfejlesztésrõl. Tisztázva és egyszerûsítve a példákat a felmerült bonyolultságok eltûnnek. Nincs, ami helyettesítené a valódi programok írását, ha benyomást akarunk kapni, igazából milyen is a programozás és egy programozási nyelv. Ez a könyv a nyelvi tulajdonságokra és az alapvetõ eljárásokra összpontosít, amelyekbõl minden program összetevõdik, valamint az összeépítés szabályaira. A példák megválasztása tükrözi fordítóprogramokkal, alapkönyvtárakkal, szimulációkkal jellemezhetõ hátteremet. A példák egyszerûsített változatai a valódi kódban találhatóknak. Egyszerûsítésre van szükség, hogy a programozási nyelv és a tervezés lényeges szempontjai el ne vesszenek a részletekben. Nincs „ügyes” példa, amelynek nincs megfelelõje a valódi kódban. Ahol csak lehetséges, a „C” függelékben lévõ nyelvtechnikai példákat olyan alakra hoztam, ahol a változók x és y, a típusok A és B, a függvények f() és g() nevûek. A kódpéldákban az azonosítókhoz változó szélességû betûket használunk. Például: #include int main() { std::cout =

// egyenlõ // nem egyenlõ // kisebb // nagyobb // kisebb vagy egyenlõ // nagyobb vagy egyenlõ

Értékadásokban és aritmetikai mûveletekben a C++ az alaptípusok között elvégez minden értelmes átalakítást, így azokat egymással tetszés szerint keverhetjük:

32

Bevezetés

void some_function() { double d = 2.2; int i = 7; d = d+i; i = d*i; }

// értéket vissza nem adó függvény // lebegõpontos szám kezdeti értékadása // egész kezdeti értékadása // összeg értékadása // szorzat értékadása

Itt = az értékadó mûvelet jele és == az egyenlõséget teszteli, mint a C-ben.

2.3.2. Elágazások és ciklusok A C++ az elágazások és ciklusok kifejezésére rendelkezik a hagyományos utasításkészlettel. Íme egy egyszerû függvény, mely a felhasználótól választ kér és a választól függõ logikai értéket ad vissza: bool accept() { cout > answer;

}

// kérdés kiírása // válasz beolvasása

if (answer == 'y') return true; return false;

A > („olvasd be”) a bemenet mûveleti jele, a cin a szabványos bemenõ adatfolyam. A >> jobb oldalán álló kifejezés határozza meg, milyen bemenet fogadható el és ez a beolvasás célpontja. A \n karakter a kiírt karakterlánc végén új sort jelent. A példa kissé javítható, ha egy 'n' választ is számításba veszünk: bool accept2() { cout > answer;

// kérdés kiírása // válasz beolvasása

2. Kirándulás a C++-ban

}

33

switch (answer) { case 'y': return true; case 'n': return false; default: cout answer;

// kérdés kiírása // válasz beolvasása

switch (answer) { case 'y': return true; case 'n': return false; default: cout > átugorja az üreshely (whitespace) karaktereket, az ilyenekkel elválasztott egészeket az alábbi egyszerû ciklussal olvashatjuk be: int read_ints(vector& v) // feltölti v-t , visszatér a beolvasott egészek számával { int i = 0; while (i>v[i]) i++; return i; }

Ha a bemeneten egy nem egész érték jelenik meg, a bemeneti mûvelet hibába ütközik, így a ciklus is megszakad. Például ezt a bemenetet feltételezve: 1 2 3 4 5.6 7 8.

a read_ints() függvény öt egész számot fog beolvasni: 12345

A mûvelet után a bemeneten a következõ beolvasható karakter a pont lesz. A nem látható üreshely (whitespace) karakterek meghatározása itt is ugyanaz, mint a szabványos C-ben (szóköz, tabulátor, újsor, függõleges tabulátorra illesztés, kocsivissza), és a fejállományban levõ isspace() függvénnyel ellenõrizhetõk valamely karakterre (§20.4.2). Az istream objektumok használatakor a leggyakoribb hiba, hogy a bemenet nem egészen abban a formátumban érkezik, mint amire felkészültünk, ezért a bemenet nem történik meg. Ezért mielõtt használni kezdenénk azokat az értékeket, melyeket reményeink szerint beolvastunk, ellenõriznünk kell a bemeneti adatfolyam állapotát (§21.3.3), vagy kivételeket kell használnunk (§21.3.6). A bemenethez használt formátumot a helyi sajátosságok (locale) határozzák meg (§21.7). Alapértelmezés szerint a logikai értékeket a 0 (hamis) és az 1 (igaz) érték jelzi, az egészeket tízes számrendszerben kell megadnunk, a lebegõpontos számok formája pedig olyan, ahogy a C++ programokban írhatjuk azokat. A basefield (§21.4.2) tulajdonság beállításával lehetõség van arra is, hogy a 0123 számot a 83 tízes számrendszerbeli szám oktális alakjaként, a 0xff bemenetet pedig a 255 hexadecimális alakjaként értelmezzük. A mutatók beolvasásához használt formátum teljesen az adott nyelvi változattól függ (nézzünk utána, saját fejlesztõrendszerünk hogyan mûködik).

826

A standard könyvtár

Meglepõ módon nincs olyan >> tagfüggvény, mellyel egy karaktert olvashatnánk be. Ennek oka az, hogy a >> operátor a karakterekhez a get() karakter-beolvasó függvény (§21.3.4) segítségével könnyen megvalósítható, így nem kell tagfüggvényként szerepelnie. Az adatfolyamokról saját karaktertípusaiknak megfelelõ karaktereket olvashatunk be. Ha ez a karaktertípus a char, akkor beolvashatunk signed char és unsigned char típusú adatot is: template basic_istream& operator>>(basic_istream&, Ch&); template basic_istream& operator>>(basic_istream&, unsigned char&); template basic_istream& operator>>(basic_istream&, signed char&);

A felhasználó szempontjából teljesen mindegy, hogy a >> tagfüggvény vagy önálló eljárás-e. A többi >> operátorhoz hasonlóan ezek a függvények is elõször átugorják a bevezetõ üreshely karaktereket: void f() { char c; cin >> c; // ... }

Ez a kódrészlet az elsõ nem üreshely karaktert a cin adatfolyamból a c változóba helyezi. A beolvasás célja lehet karaktertömb is: template basic_istream& operator>>(basic_istream&, Ch*); template basic_istream& operator>>(basic_istream&, unsigned char*); template basic_istream& operator>>(basic_istream&, signed char*);

Ezek a mûveletek is eldobják a bevezetõ üreshely karaktereket, majd addig olvasnak, amíg egy üreshely karakter vagy fájlvége jel nem következik, végül a karaktertömb végére egy 0 karaktert írnak. Természetesen ez a megoldás alkalmat ad a túlcsordulásra, így érdemesebb inkább egy string objektumba (§20.3.15) helyezni a beolvasott adatokat. Ha mégis az elõbbi

21. Adatfolyamok

827

megoldást választjuk, rögzítsük, hogy legfeljebb hány karaktert akarunk beolvasni a >> operátor segítségével. Az is.width(n) függvényhívással azt határozzuk meg, hogy a következõ, is bemeneti adatfolyamon végrehajtott >> mûvelet legfeljebb n-1 karaktert olvashat be: void g() { char v[4]; cin.width(4); cin >> v; cout >buf) os buf mûvelet egy referenciát ad vissza, amely az is adatfolyamra hivatkozik, a vizsgálatot pedig az is::operator void*() mûvelet végzi: void f(istream& i1, istream& { iocopy(i1,cout); iocopy(i2,cout); iocopy(i3,cout); iocopy(i4,cout); }

i2, istream& i3, istream& i4) // komplex számok másolása // kétszeres pontosságú lebegõpontos számok másolása // karakterek másolása // üreshelyekkel elválasztott szavak másolása

21.3.4. Karakterek beolvasása A >> operátor formázott bemenetre szolgál, tehát adott típusú és adott formátumú objektumok beolvasására. Ha erre nincs szükségünk és inkább valóban karakterekként akarjuk beolvasni a karaktereket, hogy késõbb mi dolgozzuk fel azokat, használjuk a get() függvényeket: template class basic_istream : virtual public basic_ios { public: // ... // formázatlan bemenet streamsize gcount() const;

// a legutóbbi get() által beolvasott karakterek száma

int_type get();

// egy Ch (vagy Tr::eof()) beolvasása

basic_istream& get(Ch& c);

// egy Ch olvasása c-be

basic_istream& get(Ch* p, streamsize n); basic_istream& get(Ch* p, streamsize n, Ch term);

// újsor a lezárójel

830

A standard könyvtár

basic_istream& getline(Ch* p, streamsize n); // újsor a lezárójel basic_istream& getline(Ch* p, streamsize n, Ch term);

};

basic_istream& ignore(streamsize n = 1, int_type t = Tr::eof()); basic_istream& read(Ch* p, streamsize n); // legfeljebb n karakter beolvasása // ...

Ezek mellett a fejállomány biztosítja a getline() függvényt is, amely a szabványos string-ek (§20.3.15) beolvasására használható. A get() és a getline() függvények ugyanúgy kezelik az üreshely karaktereket, mint bármely más karaktert. Kifejezetten olyan adatok beolvasására szolgálnak, ahol nem számít a beolvasott karakterek jelentése. Az istream::get(char&) függvény egyetlen karaktert olvas be paraméterébe. Egy karakterenként másoló programot például a következõképpen írhatunk meg. int main() { char c; while(cin.get(c)) cout.put(c); }

A háromparaméterû s.get(p,n,term) legfeljebb n-1 karaktert olvas be a p[0],…, p[n-2] tömbbe. A get() az átmeneti tárban mindenképpen elhelyez egy 0 karaktert a beolvasott karakterek után, így a p mutatónak egy legalább n karakter méretû tömbre kell mutatnia. A harmadik paraméter (term) az olvasást lezáró karaktert határozza meg. A háromparaméterû get() leggyakoribb felhasználási módja az, hogy beolvasunk egy „sort” egy rögzített méretû tárba és késõbb innen használjuk fel karaktereit: void f() { char buf[100]; cin >> buf; cin.get(buf,100,'\n'); // ... }

// gyanús: túlcsordulhat // biztonságos

Ha a get() megtalálja a lezáró karaktert, az adatfolyamban hagyja, tehát a következõ bemeneti mûvelet ezt a karaktert kapja meg elsõként. Soha ne hívjuk meg újra a get() függvényt a lezáró karakter eltávolítása nélkül. Ha egy get() vagy getline() függvény egyetlen karaktert sem olvas és távolít el az adatfolyamról meghívódik setstate(failbit), így a következõ beolvasások sikertelenek lesznek (vagy kivétel váltódik ki, 21.3.6).

21. Adatfolyamok

831

void subtle_error { char buf[256];

}

while (cin) { cin.get(buf,256); // a sor beolvasása cout (istream& s, complex& a) /* a complex típus lehetséges bemeneti formátumai ("f" lebegõpontos szám) f (f) (f,f) */ {

834

A standard könyvtár

double re = 0, im = 0; char c = 0; s >> c; if (c == '(') { s >> re >> c; if (c == ',') s >> im >> c; if (c != ')') s.clear(ios_base::failbit); } else { s.putback(c); s >> re; }

}

// állapot beállítása

if (s) a = complex(re,im); return s;

A nagyon kevés hibakezelõ utasítás ellenére ez a programrészlet szinte minden hibatípust képes kezelni. A lokális c változónak azért adunk kezdõértéket, hogy ha az elsõ >> mûvelet sikertelen, nehogy véletlenül pont a ( karakter legyen benne. Az adatfolyam állapotának ellenõrzésére a függvény végén azért van szükség, mert az a paraméter értékét csak akkor változtathatjuk meg, ha a korábbi mûveleteket sikeresen végrehajtottuk. Ha formázási hiba történik az adatfolyam állapota failbit lesz. Azért nem badbit, mert maga az adatfolyam nem sérült meg. A felhasználó a clear() függvénnyel alapállapotba helyezheti az adatfolyamot és továbblépve értelmes adatokat nyerhet onnan. Az adatfolyam állapotának beállítására szolgáló függvény neve clear(), mert általában arra használjuk, hogy az adatfolyam állapotát good() értékre állítsuk. Az ios_base::clear() (§21.3.3) paraméterének alapértelmezett értéke ios_base::goodbit.

21.3.6. Kivételek Nagyon kényelmetlen minden egyes I/O mûvelet után külön ellenõrizni, hogy sikeres volte, ezért nagyon gyakori hiba, hogy elfelejtünk egy ellenõrzést ott, ahol feltétlenül szükség van rá. A kimeneti mûveleteket általában nem ellenõrzik, annak ellenére, hogy néha ott is elõfordulhat hiba. Egy adatfolyam állapotának közvetlen megváltoztatására csak a clear() függvényt használhatjuk. Ezért ha értesülni akarunk az adatfolyam állapotának megváltozásáról, elég nyilvánvaló módszer, hogy a clear() függvényt kivételek kiváltására kérjük. Az ios_base osztály exceptions() tagfüggvénye pontosan ezt teszi:

21. Adatfolyamok

835

template class basic_ios : public ios_base { public: // ...

};

class failure;

// kivételosztály (lásd §14.10)

iostate exceptions() const; void exceptions(iostate except);

// kivétel-állapot kiolvasása // kivétel-állapot beállítása

// ...

A következõ utasítással például elérhetjük, hogy a clear() egy ios_base::failure kivételt váltson ki, ha a cout adatfolyam bad, fail vagy eof állapotba kerül, vagyis ha valamelyik mûvelet nem hibátlanul fut le: cout.exceptions(ios_base::badbit|ios_base::failbit|ios_base::eofbit);

Ha szükség van rá, a cout vizsgálatával pontosan megállapíthatjuk, milyen probléma történt. Ehhez hasonlóan a következõ utasítással azokat a ritkának egyáltalán nem nevezhetõ eseteket dolgozhatjuk fel, amikor a beolvasni kívánt adatok formátuma nem megfelelõ, és ennek következtében a bemeneti mûvelet nem ad vissza értéket: cin.exceptions(ios_base::badbit|ios_base::failbit);

Ha az exceptions() függvényt paraméterek nélkül hívjuk meg, akkor azokat az I/O állapotjelzõket adja meg, amelyek kivételt váltanak ki: void print_exceptions(ios_base& ios) { ios_base::iostate s = ios.exceptions(); if (s&ios_base::badbit) cout s;

utasítássorozat egyenértékû az alábbival: cout > s;

Adott idõben minden adatfolyamhoz legfeljebb egy ostream objektum köthetõ. Az s.tie(0) utasítással leválaszthatjuk az s objektumhoz kötött adatfolyamot (ha volt ilyen). A többi olyan adatfolyam-függvényhez hasonlóan, melyek értéket állítanak be, a tie(s) is a korábbi értéket adja vissza, tehát a legutóbb ide kötött adatfolyamot, vagy ha ilyen nincs, akkor a 0 értéket. Ha a tie() függvényt paraméterek nélkül hívjuk meg, akkor egyszerûen visszakapjuk az aktuális értéket, annak megváltoztatása nélkül. A szabványos adatfolyamok esetében a cout hozzá van kötve a cin bemenethez, a wcout pedig a wcin adatfolyamhoz. A cerr adatfolyamot felesleges lenne bármihez is hozzákötni, mivel ehhez nincs átmeneti tár, a clog pedig nem vár felhasználói közremûködést.

838

A standard könyvtár

21.3.8. Õrszemek Amikor a > operátort a complex típusra használtuk, egyáltalán nem foglalkoztunk az összekötött adatfolyamok (§21.3.7) kérdésével, vagy azzal, hogy az adatfolyam állapotának megváltozása kivételeket okoz-e (§21.3.6). Egyszerûen azt feltételeztük (és nem ok nélkül), hogy a könyvtár által kínált függvények figyelnek helyettünk ezekre a problémákra. De hogyan képesek erre? Néhány tucat ilyen függvénnyel kell megbirkóznunk, így ha olyan bonyolult eljárásokat kellene készítenünk, amely az összekötött adatfolyamokkal, a helyi sajátosságokkal (locale, §21.7, §D), a kivételekkel, és egyebekkel is foglalkoznak, akkor igen kusza kódot kapnánk. A megoldást a sentry („õrszem”) osztály bevezetése jelenti, amely a közös kódrészleteket tartalmazza. Azok a részek, melyeknek elsõként kell lefutniuk (a „prefix kód”, például egy lekötött adatfolyam kiürítése), a sentry konstruktorában kaptak helyet. Az utolsóként futó sorokat (a „suffix kódokat”, például az állapotváltozások miatt elvárt kivételek kiváltását) a sentry destruktora határozza meg: template class basic_ostream : virtual public basic_ios { // ... class sentry; // ... }; template class basic_ostream::sentry { public: explicit sentry(basic_ostream& s); ~sentry(); operator bool(); };

// ...

Tehát egy általános kódot írtunk, melynek segítségével az egyes függvények a következõ formába írhatók: template basic_ostream& basic_ostream::operators>>x) try { current = m.insert(current,make_pair(s,x)); } catch(...) { // itt a "current" még mindig az aktuális elemet jelöli } }

1290

Függelékek és tárgymutató

E.4.2. Garanciák és kompromisszumok Az alapbiztosításon túli szolgáltatások összevisszaságai a megvalósítási lehetõségekkel magyarázhatók. A programozók azt szeretnék leginkább, hogy mindenhol erõs biztosítás álljon rendelkezésükre a lehetõ legkevesebb korlátozás mellett, de ugyanakkor azt is elvárják, hogy a standard könyvtár minden mûvelete optimálisan hatékony legyen. Mindkét elvárás jogos, de sok mûvelet esetében lehetetlen egymással párhuzamosan megvalósítani. Ahhoz, hogy jobban megvilágítsuk az elkerülhetetlen kompromisszumokat, megvizsgáljuk, milyen módokon lehet egy vagy több elemet felvenni egy listába, vektorba vagy map-be. Nézzük elõször, hogy egy elemet hogyan vihetünk be egy listába vagy egy vektorba. Szokás szerint, a push_back() nyújtja a legegyszerûbb lehetõséget: void f(list& lst, vector& vec, const X& x) { try { lst.push_back(x); // hozzáadás a listához } catch (...) { // lst változatlan return; } try { vec.push_back(x); // hozzáadás a vektorhoz } catch (...) { // vec változatlan return; } // lst és vec egy-egy x értékû új elemmel rendelkezik }

Az erõs biztosítás megvalósítása ez esetben egyszerû és „olcsó”. Az eljárás azért is hasznos, mert teljesen kivételbiztos megoldást ad az elemek felvételére. A push_back() azonban asszociatív tárolókra nem meghatározott: a map osztályban nincs back(). Egy asszociatív tároló esetében az utolsó elemet a rendezés határozza meg, nem a pozíció. Az insert() függvény garanciái már kicsit bonyolultabbak. A gondot az jelenti, hogy az insert() mûveletnek gyakran kell egy elemet a tároló „közepén” elhelyeznie. Láncolt adatszerkezeteknél ez nem jelent problémát, tehát a list és a map egyszerûen megvalósítható, a vector esetében azonban elõre lefoglalt terület áll rendelkezésünkre, a vector::insert() függvény egy átlagos megvalósítása pedig a beszúrási pont utáni elemeket áthelyezi, hogy helyet csináljon az új elem számára. Ez az optimális megoldás, de arra nincs egyszerû mód-

E. Kivételbiztosság a standard könyvtárban

1291

szer, hogy a vektort visszaállítsuk eredeti állapotába, ha valamelyik elem másoló értékadása vagy másoló konstruktora kivételt vált ki (lásd §E.8[10-11]), ezért a vector azzal a feltétellel ad biztosításokat, hogy az elemek másoló konstruktora nem vált ki kivételt. A list és a map osztálynak nincs szüksége ilyen korlátozásra, ezek könnyedén be tudják illeszteni az új elemet a szükséges másolások elvégzése után. Példaképpen tételezzük fel, hogy az X másoló konstruktora és másoló értékadása egy X::cannot_copy kivételt vált ki, ha valamilyen okból nem sikerül létrehoznia a másolatot: void f(list& lst, vector& vec, map& m, const X& x, const string& s) { try { lst.insert(lst.begin(),x); // hozzáadás a listához } catch (...) { // lst változatlan return; } try { vec.insert(vec.begin(),x); // hozzáadás a vektorhoz } catch (X::cannot_copy) { // hoppá: vec vagy rendelkezik, vagy nem rendelkezik új elemmel return; } catch (...) { // vec változatlan return; } try { m.insert(make_pair(s,x)); // hozzáadás az asszociatív tömbhöz } catch (...) { // m változatlan return; } // lst és vec egy-egy x értékû új elemmel rendelkezik // m egy új (s,x) értékû elemmel rendelkezik }

Ha X::cannot_copy kivételt kapunk, nem tudhatjuk, hogy az új elem bekerült-e a vec tárolóba. Ha sikerült beilleszteni az elemet, az érvényes állapotban lesz, de pontos értékét nem ismerjük. Az is elképzelhetõ, hogy egy X::cannot_copy kivétel után néhány elem „titokza-

1292

Függelékek és tárgymutató

tosan” megkettõzõdik (lásd §E.8[11]), másik megvalósítást alkalmazva pedig a vektor végén lévõ elemek tûnhetnek el, mert csak így lehet biztosítani, hogy a tároló érvényes állapotban maradjon és ne szerepeljenek benne érvénytelen elemek. Sajnos az erõs biztosítás megvalósítása a vector osztály insert() függvénye esetében lehetetlen, ha megengedjük, hogy az elemek másoló konstruktora kivételt váltson ki. Ha egy vektorban teljesen meg akarnánk védeni magunkat az elemek áthelyezése közben keletkezõ kivételektõl, a költségek elviselhetetlenül megnõnének az egyszerû, alapbiztosítást nyújtó megoldáshoz képest. Sajnos nem ritkák az olyan elemtípusok, melyek másoló konstruktora kivételt eredményezhet. Már a standard könyvtárban is találhatunk példát: a vector, a vector< vector > és a map is ilyen. A list és a vector tároló ugyanolyan biztosítást ad az insert() egyelemû és többelemû változatához, mert azok megvalósítási módja azonos. A map viszont erõs biztosítást ad az egyelemû beszúráshoz, míg a többelemûhöz csak alapbiztosítást. Az egyelemû insert() a map esetében könnyen elkészíthetõ erõs biztosítással, a többelemû változat egyetlen logikus megvalósítási módja azonban a map esetében az, hogy az új elemeket egymás után szúrjuk be, és ehhez már nagyon nehéz lenne erõs garanciákat adni. A gondot itt az jelenti, hogy nincs egyszerû visszalépési lehetõség (nem tudunk korábbi sikeres beszúrásokat visszavonni), ha valamelyik elem beszúrása nem sikerül. Ha olyan többelemû beszúró mûveletre van szükségünk, amely erõs biztosítást ad, azaz vagy minden elemet hibátlanul beilleszt, vagy egyáltalán nem változtatja meg a tárolót, legegyszerûbben úgy valósíthatjuk meg, hogy egy teljesen új tárolót készítünk, majd ennek sikeres létrehozása után egy swap() mûveletet alkalmazunk: template void safe_insert(C& c, typename C::const_iterator i, Iter begin, Iter end) { C tmp(c.begin(),i); // az elöl levõ elemek másolása ideiglenes változóba copy(begin,end,inserter(tmp,tmp.end())); // új elemek másolása copy(i,c.end(),inserter(tmp,tmp.end())); // a záró elemek másolása swap(c,tmp); }

Szokás szerint, ez a függvény is hibásan viselkedhet, ha az elemek destruktora kivételt vált ki, ha viszont az elemek másoló konstruktora okoz hibát, a paraméterben megadott tároló változatlan marad.

E. Kivételbiztosság a standard könyvtárban

1293

E.4.3. A swap() A másoló konstruktorokhoz és értékadásokhoz hasonlóan a swap() eljárások is nagyon fontos szerepet játszanak sok szabványos algoritmusban és közvetlenül is gyakran használják a felhasználók. A sort() és a stable_sort() például általában a swap() segítségével rendezi át az elemeket. Tehát ha a swap() kivételt vált ki, miközben a tárolóban szereplõ értékeket cserélgeti, akkor a tároló elemei a csere helyett vagy változatlanok maradnak, vagy megkettõzõdnek. Vizsgáljuk meg a standard könyvtár swap() függvényének alábbi, egyszerû megvalósítását (§18.6.8): template void swap(T& a, T& b) { T tmp = a; a = b; b = tmp; }

Erre teljesül, hogy a swap() csak akkor eredményezhet kivételt, ha azt az elemek másoló konstruktora vagy másoló értékadása váltja ki. Az asszociatív tárolóktól eltekintve a szabványos tárolók biztosítják, hogy a swap() függvény ne váltson ki kivételeket. A tárolókban általában úgy is meg tudjuk valósítani a swap() függvényt, hogy csak az adatszerkezeteket cseréljük fel, melyek mutatóként szolgálnak a tényleges elemekhez (§13.5, §17.1.3). Mivel így magukat az elemeket nem kell mozgatnunk, azok konstruktorára vagy értékadó mûveletére nincs szükségünk, tehát azok nem kapnak lehetõséget kivétel kiváltására. Ezenkívül a szabvány biztosítja, hogy a könyvtár swap() függvénye nem tesz érvénytelenné egyetlen hivatkozást, mutatót és bejárót sem azok közül, melyek a felcserélt tárolók elemeire hivatkoznak. Ennek következtében kivételek egyetlen ponton léphetnek fel: az asszociatív tárolók összehasonlító objektumaiban, melyeket az adatszerkezet leírójának részeként kell másolnunk. Tehát az egyetlen kivétel, amit a szabványos tárolók swap() eljárása eredményezhet, az összehasonlító objektum másoló konstruktorából vagy értékadó mûveletébõl származik (§17.1.4.1). Szerencsére az összehasonlító objektumoknak általában annyira egyszerû másoló mûveleteik vannak, hogy nincs lehetõségük kivétel kiváltására. A felhasználói swap() függvények viszonylag egyszerûen nyújthatnak ugyanilyen biztosításokat, ha gondolunk rá, hogy „mutatókkal” ábrázolt adatok esetében elegendõ csak a mutatókat felcserélnünk, ahelyett, hogy lassan és precízen lemásolnánk a mutatók által kijelölt tényleges adatokat (§13.5, §16.3.9, §17.1.3).

1294

Függelékek és tárgymutató

E.4.4. A kezdeti értékadás és a bejárók Az elemek számára való memóriafoglalás és a memóriaterületek kezdeti értékadása alapvetõ része minden tárolónak (§E.3). Ebbõl következik, hogy a fel nem töltött (elõkészítetlen) memóriaterületen objektumot létrehozó szabványos eljárások – az uninitialized_fill(), az uninitialized_fill_n() és az uninitialized_copy() (§19.4.4) – semmiképpen sem hagyhatnak létrehozott objektumokat a memóriában, ha kivételt váltanak ki. Ezek az algoritmusok erõs biztosítást valósítanak meg (§E.2), amihez gyakran kell elemeket törölni, tehát az a követelmény, miszerint a destruktoroknak tilos kivételt kiváltaniuk, elengedhetetlen ezeknél a függvényeknél is (lásd §E.8[14]). Ezenkívül azoknak a bejáróknak is megfelelõen kell viselkedniük, melyeket paraméterként adunk át ezeknek az eljárásoknak. Tehát érvényes bejáróknak kell lenniük, érvényes sorozatokra kell hivatkozniuk, és a bejáró mûveleteknek (például a ++, a != vagy a * operátornak) nem szabad kivételt kiváltaniuk, ha érvényes bejárókra alkalmazzuk azokat. A bejárók (iterátorok) olyan objektumok, melyeket a szabványos algoritmusok és a szabványos tárolók mûveletei szabadon lemásolhatnak, tehát ezek másoló konstruktora és másoló értékadása nem eredményezhet kivételt. A szabvány garantálja, hogy a szabványos tárolók által visszaadott bejárók másoló konstruktora és másoló értékadása nem vált ki kivételt, így a vector::begin() által visszaadott bejárót például nyugodtan lemásolhatjuk, nem kell kivételtõl tartanunk. Figyeljünk rá, hogy a bejárókra alkalmazott ++ vagy -- mûvelet eredményezhet kivételt. Például egy istreambuf_iterator (§19.2.6) egy bemenethibát (logikusan) egy kivétel kiváltásával jelezhet, egy tartományellenõrzött bejáró pedig teljesen szabályosan jelezheti kivétellel azt, hogy megpróbáltunk kilépni a megengedett tartományból (§19.3). Akkor azonban nem eredményezhetnek kivételt, ha a bejárót úgy irányítjuk át egy sorozat egyik elemérõl a másikra, hogy közben a ++ vagy a -- egyetlen szabályát sem sértjük meg. Tehát az uninitialized_fill(), az uninitialized_fill_n() és az uninitialized_copy() feltételezi, hogy a bejárókra alkalmazott ++ és -- mûvelet nem okoz kivételt. Ha ezt mégis megteszik, a szabvány megfogalmazása szerint ezek nem is igazán bejárók, vagy az általuk megadott „sorozat” nem értelmezhetõ sorozatként. Most is igaz, hogy a szabvány nem képes megvédeni a felhasználót a saját maga által okozott nem meghatározható viselkedéstõl (§E.2).

E.4.5. Hivatkozások elemekre Ha elemre hivatkozó mutatót, referenciát vagy bejárót adunk át egy eljárásnak, az tönkreteheti a listát azzal, hogy az adott elemet érvénytelenné teszi:

E. Kivételbiztosság a standard könyvtárban

1295

void f(const X& x) { list lst; lst.push_back(x); list::iterator i = lst.begin(); *i = x; // x listába másolása // ... }

Ha az x változóban érvénytelen érték szerepel, a list destruktora nem képes hibátlanul megsemmisíteni az lst objektumot: struct X { int* p;

};

X() { p = new int; } ~X() { delete p; } // ...

void malicious() { X x; x.p = reinterpret_cast(7); f(x); }

// hibás x // idõzített bomba

Az f() végrehajtásának befejeztével meghívódik a list destruktora, amely viszont meghívja az X destruktorát egy érvénytelen értékre. Ha megpróbáljuk a delete p parancsot végrehajtani egy olyan p értékre, amely nem 0 és nem is létezõ X típusú értékre mutat, az eredmény nem meghatározható lesz és akár a rendszer azonnali összeomlását okozhatja. Egy másik lehetõség, hogy a memória érvénytelen állapotba kerül, ami sokkal késõbb, a program olyan részében okoz „megmagyarázhatatlan” hibákat, amely teljesen független a tényleges problémától. Ez a hibalehetõség nem gátolja meg a programozókat abban, hogy referenciákat és bejárókat használjanak a tárolók elemeinek kezelésére, hiszen mindenképpen ez az egyik legegyszerûbb és leghatékonyabb módszer az ilyen feladatok elvégzéséhez. Mindenesetre érdemes különösen elõvigyázatosnak lennünk a tárolók elemeire való hivatkozásokkal kapcsolatban. Ha egy tároló épsége veszélybe kerülhet, érdemes a kevésbé gyakorlott felhasználók számára biztonságosabb, ellenõrzött változatokat is készítenünk, például megadhatunk egy olyan eljárást, amely ellenõrzi, hogy az új elem érvényes-e, mielõtt beszúrja azt a „fontos” tárolóba. Természetesen ilyen ellenõrzéseket csak akkor végezhetünk, ha pontosan ismerjük a tárolóban tárolt elemek típusát.

1296

Függelékek és tárgymutató

Általában, ha egy tároló valamelyik eleme érvénytelenné válik, a tárolóra alkalmazott minden további mûvelet hibákat eredményezhet. Ez nem csak a tárolók sajátja: bármely objektum, amely valamilyen szempontból hibás állapotba kerül, a késõbbiekben bármikor okozhat problémákat.

E.4.6. Predikátumok Számos szabványos algoritmus és tároló használ olyan predikátumokat, melyeket a felhasználók adhatnak meg. Az asszociatív tárolók esetében ezek különösen fontos szerepet töltenek be: az elemek keresése és beszúrása is ezen alapul. A szabványos tárolók mûveletei által használt predikátumok is okozhatnak kivételeket, és ha ez bekövetkezik, a standard könyvtár mûveletei legalább alapbiztosítást nyújtanak, de sok esetben (például az egyelemû insert() mûveletnél) erõs biztosítás áll rendelkezésünkre (§E.4.1). Ha egy tárolóján végzett mûvelet közben egy predikátum kivételt vált ki, elképzelhetõ, hogy az ott tárolt elemek nem pontosan azok lesznek, amelyeket szeretnénk, de mindenképpen érvényes elemek. Például ha az == okoz kivételt a list::unique() (§17.2.2.3) mûvelet végrehajtása közben, nem várhatjuk el, hogy minden értékismétlõdés eltûnjön. A felhasználó mindössze annyit feltételezhet, hogy a listában szereplõ értékek érvényesek maradnak (lásd §E.5.3). Szerencsére a predikátumok ritkán csinálnak olyasmit, ami kivételt eredményezhet. Ennek ellenére a felhasználói szerkezetet kell használnunk. Ez a megoldás az egész programot rugalmasabbá teszi. Amikor új programot készítünk, lehetõségünk van arra, hogy átgondoltabb megközelítést találjunk és biztosítsuk, hogy erõforrásainkat olyan osztályokkal ábrázoljuk, melyek invariánsa alapbiztosítást nyújt (§E.2). Egy ilyen rendszerben lehetõség nyílik arra, hogy kiválasszuk a létfontosságú objektumokat és ezek mûveleteihez visszagörgetési módszereket alkalmazzunk (azaz erõs biztosítást adhatunk – néhány egyedi feltétel mellett).

1302

Függelékek és tárgymutató

A legtöbb program tartalmaz olyan adatszerkezeteket és programrészeket, melyeket a kivételbiztosságra nem gondolva írtak meg. Ha szükség van rá, ezek a részek egy kivételbiztos keretbe ágyazhatók. Az egyik lehetõség, hogy biztosítjuk, hogy kivételek ne következzenek be (ez történt a C standard könyvtárával, §E.5.5), a másik megoldás pedig az, hogy felületosztályokat használunk, melyekben a kivételek viselkedése és az erõforrások kezelése pontosan meghatározható. Amikor olyan új típusokat tervezünk, amelyek kivételbiztos környezetben futnak majd, külön figyelmet kell szentelnünk azoknak az eljárásoknak, melyeket a standard könyvtár használni fog: a konstruktoroknak, a destruktoroknak, az értékadásoknak, összehasonlításoknak, swap függvényeknek, a predikátumként használt függvényeknek és a bejárókat kezelõ eljárásoknak. Ezt legkönnyebben úgy valósíthatjuk meg, hogy egy jó osztályinvariánst határozunk meg, amelyet minden konstruktor könnyedén biztosíthat. Néha úgy kell megterveznünk az osztályinvariánst, hogy az objektumoknak legyen egy olyan állapota, melyben egyszerûen törölhetõk, ha egy mûvelet „kellemetlen” helyen ütközik hibába. Ideális esetben ez az állapot nem egy mesterségesen megadott érték, amit csak a kivételkezelés miatt kellett bevezetni, hanem az osztály természetébõl következõ állapot (§E.3.5). Amikor kivételbiztossággal foglalkozunk, a fõ hangsúlyt az objektumok érvényes állapotainak (invariánsainak) meghatározására és az erõforrások megfelelõ felszabadítására kell helyeznünk. Ezért nagyon fontos, hogy az erõforrásokat közvetlenül osztályokkal ábrázoljuk. A vector_base (§E.3.2) ennek egyszerû példája. Az ilyen erõforrás-osztályok konstruktora alacsonyszintû erõforrásokat foglal le (például egy memóriatartományt a vector_base esetében), és invariánsokat állít be (például a mutatókat a megfelelõ helyekre állítja a vector_base osztályban). Ezen osztályok destruktora egyszerûen felszabadítja a lefoglalt erõforrást. A részleges létrehozás szabályai (§14.4.1) és a „kezdeti értékadás az erõforrás lefoglalásával” módszer (§14.4) alkalmazása lehetõvé teszi, hogy az erõforrásokat így kezeljük. Egy jól megírt konstruktor minden objektum esetében beállítja a megfelelõ invariánst (§24.3.7.1), tehát a konstruktor olyan értéket ad az objektumnak, amely lehetõvé teszi, hogy a további mûveleteket egyszerûen meg tudjuk írni és sikeresen végre tudjuk hajtani. Ebbõl következik, hogy a konstruktoroknak gyakran kell erõforrást lefoglalniuk. Ha ezt nem tudják elvégezni, kivételt válthatnak ki, így az objektum létrehozása elõtt foglalkozhatunk a jelentkezõ problémákkal. Ezt a megközelítést a nyelv és a standard könyvtár közvetlenül támogatja (§E.3.5). Az a követelmény, hogy az erõforrásokat fel kell szabadítanunk és az operandusokat érvényes állapotban kell hagynunk a kivétel kiváltása elõtt, azt jelenti, hogy a kivételkezelés terheit megosztjuk a kivételt kiváltó függvény, a hívási láncban levõ függvények és a kivételt ténylegesen kezelõ eljárás között. Egy kivétel kiváltása nem azt a hibakezelési stílust jelen-

E. Kivételbiztosság a standard könyvtárban

1303

ti, hogy „hagyjuk az egészet valaki másra”. Minden függvénynek, amely kivételt vált ki vagy ad tovább, kötelessége felszabadítani azokat az erõforrásokat, melyek hatáskörébe tartoznak, operandusait pedig megfelelõ értékre kell állítania. Ha az eljárások ezt a feladatot nem képesek végrehajtani, a kivételkezelõ nemigen tehet mást, minthogy megpróbálja „szépen” befejezni a program mûködését.

E.7. Tanácsok [1] Legyünk tisztában azzal, milyen szintû kivételbiztosságra van szükségünk. §E.2. [2] A kivételbiztosságnak egy teljes körû hibatûrési stratégia részének kell lennie. §E.2. [3] Az alapbiztosítást minden osztályhoz érdemes megvalósítani, azaz az invariánsokat mindig tartsuk meg és az erõforrás-lyukakat mindig kerüljük el. §E.2, §E.3.2, §E.4. [4] Ahol lehetõség és szükség van rá, valósítsunk meg erõs biztosítást, azaz egy mûvelet vagy sikeresen hajtódjon végre, vagy minden operandusát hagyja változatlanul. §E.2, §E.3. [5] Destruktorokban ne fordulhasson elõ kivétel. §E.2, §E.3.2, §E.4. [6] Ne váltson ki kivételt egy érvényes sorozatban mozgó bejáró. §E.4.1, §E.4.4. [7] A kivételbiztosság foglalja magában az önálló mûveletek alapos vizsgálatát. §E.3. [8] A sablon osztályokat úgy tervezzük meg, hogy azok „átlátszóak” legyenek a kivételek számára. §E.3.1. [9] Az init() függvény helyett használjunk konstruktort az erõforrások lefoglalásához. §E.3.5. [10] Adjunk meg invariánst minden osztályhoz, hogy ezzel pontosan meghatározzuk érvényes állapotaikat. §E.2, §E.6. [11] Gyõzõdjünk meg róla, hogy objektumaink mindig érvényes állapotba állíthatók anélkül, hogy kivételektõl kellene tartanunk. §E.3.2, §E.6. [12] Az invariánsok mindig legyenek egyszerûek. §E.3.5. [13] Kivétel kiváltása elõtt minden objektumot állítsunk érvényes állapotba. §E.2, §E.6. [14] Kerüljük el az erõforrás-lyukakat. §E.2, §E.3.1, §E.6. [15] Az erõforrásokat közvetlenül ábrázoljuk. §E.3.2, §E.6. [16] Gondoljunk rá, hogy a swap() függvény gyakran használható az elemek másolása helyett. §E.3.3.

1304

Függelékek és tárgymutató

[17] Ha lehetõség van rá, a try blokkok használata helyett a mûveletek sorrendjének jó megválasztásával kezeljük a problémákat. §E.3.4. [18] Ne töröljük a „régi” információkat addig, amíg a helyettesítõ adatok nem válnak biztonságosan elérhetõvé. §E.3.3, §E.6. [19] Használjuk a „kezdeti értékadás az erõforrás megszerzésével” módszert. §E.3, §E.3.2, §E.6. [20] Vizsgáljuk meg, hogy asszociatív tárolóinkban az összehasonlító mûveletek másolhatók-e. §E.3.3. [21] Keressük meg a létfontosságú adatszerkezeteket és ezekhez adjunk meg olyan mûveleteket, melyek erõs biztosítást adnak. §E.6.

E.8. Gyakorlatok 1. (*1) Soroljuk fel az összes kivételt, amely elõfordulhat az §E.1 pont f() függvényében. 2. (*1) Válaszoljunk az §E.1 pontban, a példa után szereplõ kérdésekre. 3. (*1) Készítsünk egy Tester osztályt, amely idõnként a legalapvetõbb mûveletekben okoz kivételt, például a másoló konstruktorban. A Tester osztály segítségével próbáljuk ki saját standard könyvtárunk tárolóit. 4. (*1) Keressük meg a hibát az §E.3.1 pontban szereplõ vector konstruktorának rendezetlen változatában és írjunk programot, amely tönkreteszi az osztályt. Ajánlás: elõször írjuk meg a vector destruktorát. 5. (*2) Készítsünk egyszerû listát, amely alapbiztosítást nyújt. Állapítsuk meg nagyon pontosan, milyen követelményeket kell a felhasználónak teljesítenie a biztosítás megvalósításához. 6. (*3) Készítsünk egyszerû listát, amely erõs biztosítást nyújt. Alaposan ellenõrizzük az osztály mûködését. Indokoljuk meg, miért tartjuk ezt a megoldást biztonságosabbnak. 7. (*2.5)Írjuk újra a §11.12 String osztályát úgy, hogy ugyanolyan biztonságos legyen, mint a szabványos tárolók. 8. (*2) Hasonlítsuk össze a vector osztályban meghatározott értékadás és a safe_assign() függvény különbözõ változatait a futási idõ szempontjából. (§E.3.3) 9. (*1.5) Másoljunk le egy memóriafoglalót az értékadó operátor használata nélkül (hiszen az operator=() megvalósításához erre van szükségünk az §E.3.3 pontban).

E. Kivételbiztosság a standard könyvtárban

1305

10. (*2) Írjunk a vector osztályhoz alapbiztosítással egy egyelemû és egy többelemû erase(), illetve insert() függvényt.§E.3.2. 11. (*2) Írjunk a vector osztályhoz erõs biztosítással egy egyelemû és egy többelemû erase(), illetve insert() függvényt (§E.3.2). Hasonlítsuk össze ezen függvények költségét és bonyolultságát az elõzõ feladatban szereplõ függvényekével. 12. (*2) Készítsünk egy safe_insert() függvényt (§E.4.2), amely egy létezõ vector objektumba szúr be elemet (nem pedig egy ideiglenes változót másol le). Milyen kikötéseket kell tennünk a mûveletekre? 13. (*2.5) Hasonlítsuk össze méret, bonyolultság és hatékonyság szempontjából a 12. és a 13. feladatban szereplõ safe_insert() függvényt az §E.4.2 pontban bemutatott safe_insert() függvénnyel. 14. (*2.5) Írjunk egy jobb (gyorsabb és egyszerûbb) safe_insert() függvényt, kifejezetten asszociatív tárolókhoz. Használjuk a traits eljárást egy olyan safe_insert() megvalósításához, amely automatikusan kiválasztja az adott tárolóhoz optimális megvalósítást. Ajánlás: §19.2.3. 15. (*2.5) Próbáljuk megírni az uninitialized_fill() függvényt (§19.4.4, §E.3.1) úgy, hogy az megfelelõen kezelje a kivételeket kiváltó destruktorokat is. Lehetséges ez? Ha igen, milyen áron? Ha nem, miért nem? 16. (*2.5) Keressünk egy tárolót egy olyan könyvtárban, amely nem tartozik a szabványhoz. Nézzük át dokumentációját és állapítsuk meg, milyen kivételbiztossági lehetõségek állnak rendelkezésünkre. Végezzünk néhány tesztet, hogy megállapítsuk, mennyire rugalmas a tároló a memóriafoglalásból vagy a felhasználó által megadott programrészekbõl származó kivételekkel szemben. Hasonlítsuk össze a tapasztaltakat a standard könyvtár megfelelõ tárolójának szolgáltatásaival. 17. (*3) Próbáljuk optimalizálni az §E.3 pontban szereplõ vector osztályt a kivételek lehetõségének figyelmen kívül hagyásával. Például töröljünk minden try blokkot. Hasonlítsuk össze az így kapott változat hatékonyságát a standard könyvtár vector osztályának hatékonyságával. Hasonlítsuk össze a két változatot méret és bonyolultság szempontjából is. 18. (*1) Adjunk meg invariánst a vector osztály (§E.3) számára úgy, hogy megengedjük, illetve megtiltjuk a v==0 esetet (§E.3.5). 19. (*2.5) Nézzük végig egy vector osztály megvalósításának forráskódját. Milyen biztosítás áll rendelkezésünkre az értékadásban, a többelemû insert() utasításban és a resize() függvényben? 20. (*3) Írjuk meg a hash_map (§17.6) olyan változatát, amely ugyanolyan biztonságos, mint a szabványos tárolók.