Előadást letölteni
Az előadás letöltése folymat van. Kérjük, várjon
KiadtaZsófia Lakatosné Megváltozta több, mint 9 éve
1
Haladó C++ Programozás Az STL sablonkönyvtár felhasználói szemszögből
2013. október
2
Mai témák STL bevezető adattároló struktúrák (konténerek)
egyelőre csak alaptípusokkal léptetők (iterátorok) algoritmusok STL
3
STL sablonkönyvtár STL Szóismétlés, hiszen Mi van benne?
S: Standard =Szabvány(os(ított)) T: Template =Sablon L: Library =Könyvtár (Gyűjtemény) Mi van benne? adattárolási struktúrák (konténerek) műveletsablonok (minus, plus, …) mert a globális operátorokat nem lehet örökíteni alapértelmezett viselkedés: rendes operátorokat hívja meg (+,-,<,=,*) algoritmusok konténerekre (bepakol, kiszed, rendez, keres, feje tetejére állít, …) segédanyagok (adatelérésre, memóriakezelésre) Mi nincs benne? teljes egyetértés SGI vs. Microsoft, etc. van, ami csak ajánlás, de nem kötelező implementálni fordítási hibaüzenetekhez értelmezőszótár meg kell tanulni a többsoros hibaüzenetekből a lényeget kiolvasni Van hozzá nagyon jó dokumentáció ( Elterjedettsége nagyfokú dinamikus adatkezelést lebonyolító eljárás ma gyakorlatilag ritkaság nélküle (és értelmetlen is) STL
4
STL - koncepció Duális világ: keret (váz) + anyag (esszencia) pl.:
(nem lesz számonkérve, de segít megérteni) pl.: Ember Test Értelem Csont Hús Lélek Szellem nem testi.. attitűd fantázia STL
5
avagy... ez témájában jó példa, mert a nyelvről szól
kijelentés alany állítmány bővítmények... ez témájában jó példa, mert a nyelvről szól C++ is egy nyelv... STL
6
tervezési minták (design patterns) – félév 3. része
Ami pedig minket illet program kód adat kódsablon egyedi kód adatstuktúra egyedi adat tervezési minták (design patterns) – félév 3. része STL, főleg a konténerek, de tágabb körben a hozzájuk szorosan kapcsolódó algoritmusok is adat – kód szétválasztás megvan architekturálisan is, már az XT-ben is... Ezzel már tényleg lehet komoly kód- újrahasznosítást művelni! STL
7
Coming soon: vector<T>
vector<int> a(10); 10 hosszú int tömb for (int i=0;i<10;++i) a[i]=2*i; op[]-ral indexelt direkt elemelérés nemcsak olvasásra, hanem írásra is! a.resize(15); dinamikus átméretezés a.push_back(4); elem hozzátoldása a végéhez cout<<a.size(); méret lekérdezése (belsőleg tárolja, ellentétben int *a=new int[x]-szel) stb. olvasd: kocka operátorral (vagy operátor szögletes zárójellel) STL
8
Adattárolási struktúrák
Elvárások a konténerrel szemben Transzparens működés memóriakezelés szempontjából (new – delete elrejtése, memóriaszivárgás kiküszöbölése) dinamikus nyújtózkodás esetén másoláskor születésnél/elhaláskor Jellemzők lekérdezése méret (elemszám) legkisebb/legnagyobb elem melyik elemből mennyi van STL
9
Adattárolási struktúrák
Elvárások a konténerrel szemben Elemek közvetlen elérése Adatbeszúrás/-módosítás/-törlés Halmaz- és egyéb algoritmusok támogatása (az “elvárás” alatt azt is értsd, hogy a nagyHF- ben elvárjuk) STL
10
Konténerek Legjellemzőbb felosztás: Szekvenciális szerkezetek
a felhasználó határozza meg az elemek sorrendjét vector dinamikus méretű, közvetlen elérésű tömb list kétirányba láncolt lista deque előre-hátra dinamikusan nyújtózkodó k.e. tömb Asszociatív szerkezetek ő magának sorrendezi az elemeket, hogy hatékonyan tudja majd kezelni őket set rendezett halmaz map rendezett asszociatív tömb multiset elemismétlődést megengedő rend. halmaz multimap 1:N leképezést megengedő asszoc. tömb STL
11
Konténerek Egyéb szerkezetek Megjegyzés: hash ~_map ~_set ~_multimap
gyorsabb asszociáció, de nem egységes szabvány, ezért soruljuk az egyéb szerkezetek közé ~_map ~_set ~_multimap ~_multiset Megjegyzés: Java-ban szabványos a hash* tárolási struktúra, ott gyakrabban használjuk, C++ map<> pedig a java TreeMap<>-jához hasonlít. STL
12
Konténerek Egyéb szerkezetek Megjegyzés: hash ~_map ~_set ~_multimap
gyorsabb asszociáció, de nem egységes szabvány, ezért soruljuk az egyéb szerkezetek közé ~_map ~_set ~_multimap ~_multiset Megjegyzés: Java-ban szabványos a hash* tárolási struktúra, ott gyakrabban használjuk, C++ map<> pedig a java TreeMap<>-jához hasonlít. STL
13
Konténerek Speciális szerkezetek
slist egy irányba láncolt lista bit_vector bool értékek tárolására rope szövegeknek stack verem heap kupac queue FIFO szerkezet bitset<int> meghatározott bitszámú adatoknak karakterláncok bizonyos műveletek gyakoriabbak, célorientált optimalizálás Karakterláncokra miért készítettek sablont, miért nem csak char típusra definiálták? STL
14
Konténerek Speciális szerkezetek++ Régebbi NagyHF-k tömörítő konténer
log-olás dupla indexelésű asszociáció (mikor-hol mi a helyzet, ~ oda-vissza asszociáció kétnyelvű szótár egyéb lehetőségek... cache-elt elérés a leggyakrabban használt adatokra unpop művelet támogatása stb. STL
15
Konténerek Speciális szerkezetek++ Újabb NagyHF-k Mátrix
“flat” tárolási struktúra Beszúrás, törlés, módosítás Oszlopra, sorra, elemre Transformáció Transzponálás Aritmetika Összeadás, szorzás Determináns Inverz Asszociatív mátrix Mátrix tárolási struktúrát adottnak véli Asszociatív címzés sorra, oszlopra STL
16
A vector és a lista A vector<T> T dinamikus tömbjét valósítja meg. Az elemek közvetlen egymás után, egy tömbben vannak a memóriában. Elemeket el lehet érni tömbindexeléssel, működik a pointer-aritmetika. A túlindexelés (tömb méretén felüli elem írása/olvasása) nem definiált hatást eredményez. vector1_demo.cc vector2_demo.cc kiírórutin ostream &operator<<(ostream&, const X&) elterjedt használata, később is.. STL
17
A vector és a lista A list<T> két irányba láncolt T listát valósít meg list1_demo.cc mindkét irányban egyszerűen bővíthető/törölhető, sőt elembeszúrás is O(c) idő alatt zajlik le nincs közvetlen elérés: indexelés nincs rá értelmezve, helyette iterátorral lehet benne lépkedni list2_demo.cc beépített algoritmusok list3_demo.cc feltuningolt pointer STL
18
A vector és a lista ? ! Value_n+1 vector push_back() Value0 Value1
operator[ ](0) operator[ ](2) operator[ ](1) Value0 Value1 Value2 Value_n X pszeudo-iterator, vagyis nincs alatta érték, az opetator++() nem ad értelmes választ, de arra jó, hogy az end()-del összehasonlítsuk ? Hol van a vector esetén az iterátor? ! Az értékre mutató pointer az iterátor. list end() begin() operator++() operator++() operator++() Iterator1 Iterator2 Iterator3 IteratorN X operator--() operator*() operator*() operator*() Value1 Value2 Value3 X STL
19
vector vs. list elem elérése beszúrás attól függ, hova:
deque elem elérése beszúrás attól függ, hova: előre középre végére objektumok összefűzése, intervallumok manipulálása (insert(), erase(), copy() etc.) O(n) O(c) STL
20
coming soon: map<K,V>
map<TimeStamp, double> laz; időpontokhoz rendelünk double értékeket laz[TimeStamp(06,30)]=37.1; laz[TimeStamp(10,05)]=37.5; laz.insert(pair<TimeStamp,double>(TimeStamp(09,20),37.6)); elemek beszúrása laz[TimeStamp(06,30)]=36.9; elem felülírása double x=laz[TimeStamp(10,05)]; érték kiolvasása double y=laz[TimeStamp(00,00)]; nem definiált kulcs alól default érték kiolvasása (+ beszúrása!) map<TimeStamp,double>::iterator laz_0735it=laz.find(TimeStamp(07,35)); keresés kulcs szerint if (laz_0735it!=laz.end()) pair<TimeStamp,double> laz_0735=*laz_0735it; iterátor alatt kulcs-érték pár map<TimeStamp,double>::iterator laz_reggelit=laz.lower_bound(TimeStamp(08,00)); nem pontos, de közeli (megadottnál nagyobb kulcsú) elem keresése STL
21
Rendezett asszociatív tárolóstruktúrák (előzetes összefoglaló)
Ide tartozik map, multimap, set, multiset Erősség bizonyos algoritmusok támogatása rendezettségből adódóan a keresés O(log(n)) egyediség alapértelmezetten garantált (map, set esetében) Hogyan biztosítjuk a rugalmasságot elemeire iterátorok mutatnak (akárcsak vector, list esetében) rendezés szabálya megadható függvényosztállyal, azaz funktorral általános elérési felület (interface) begin(), end(), empty(), insert()-ek, clear(), konstruktor intervallummal külső függvényekre iterátorokkal kell illeszteni mindegyik konténert mint intervallumot STL
22
-torok latin magyarul igék:
fungor,fungi,functus végrehajt, cselekszik itero,iterare,iteravi,iteratus ismétel, hajtogat (szavakat, nem origamit) képzők (igék negyedik (passzív) alakjából): -tus/-sus → -tor/-sor cselekvő alany (ld. még: diktátor) -tus/-sus → -tion/-sion szenvedő alany magyarul functor végrehajtó iterator ismétlő STL
23
Kapcsolódás egymáshoz?
-torok rendez: < összegez: + keres: <,= léptet: ++,-- C++ Algoritmusok Műveletek funktorok iterátorok Kapcsolódás egymáshoz? másol, töröl, keres, rendez, összegez, …léptet… Beépített algoritmusok Konténer STL
24
Functor (function object)
olyan objektum, ami függvényként használható mert rendelkezik publikus operator()-ral (zárójel operátorral) haszna: egzakt típus örököltethető, stb ahová a kód egy fv.-t vár, oda beilleszthető mi közünk hozzá? STL épít rá rendezési reláció, transzformáló rutin, konténerhez feltöltőrutin... amúgy is ritkán használt szabványos nyelvi elem, tehát a HCPP kurzusnak tárgya STL
25
Functor mint rendezési reláció
A példák egymásra épülnek, bemutatják a funktor erejét: functor1.cc functor2.cc functor3.cc functor4.cc functor5.cc Tehát az ereje: képes függvényként működni inicializálható lehet belső memóriája STL
26
Iterátorok “objektummá felturbózott pointer” Mire használjuk őket?
de mint láttuk, olykor a pointer is lehet iterátor (pl. vector vagy hagyományos tömb esetén) Miért? Mert template programozás esetén (akárcsak a makróknál) nincs típusellenőrzés, csupán felhasználáskor kell, hogy a meghívott eljárás értelmezhető legyen. A pointerre az iterátor-eljárások (léptetés, értékadás, op*()) értelmezhetőek. Mire használjuk őket? lépni lehet a konténeren belül elemről elemre pontokat, intervallumokat lehet definiálni vele a konténeren belül Általánosan (mint már láthattuk): különböző tárolók interfészei algoritmusok számára pl. count() list-re, find() vectorra STL
27
Altípusai /Concepts/ (funkcionalitás szerint csoportosítva):
"trivial" iterátor - az iterátort mint emelet elérő objektumot jellemzi Konstruktor X x; Érték elérése *x; Érték módosítása *x=y; (ha X módosítható - ez nincs mindig így) Tag elérése x->m (ezt nem támogatja mindegyik fordító) STL
28
Altípusai /Concepts/ (funkcionalitás szerint csoportosítva):
előre haladó “forward iterator” (csak egy irányba léptethető) ++x; - referenciával tér vissza x++ - ekvivalens: {X tmp=i; ++i; return tmp;} kétirányú “bidirectional” (oda-vissza léphet) előre haladón túl: --x x-- STL
29
Altípusai /Concepts/ (funkcionalitás szerint csoportosítva):
közvetlen elemelérésű “random” (tetszőleges lépésközzel haladhat) kétirányún túl: pointeraritmetika (+,-,+=,-=,<) közvetlen elemelérés: x[n]; közvetlen elemmódosítás: x[n]=y; STL
30
Altípusai /Concepts/ (funkcionalitás szerint csoportosítva):
bemeneti “input” (az értéket csak kiolvasni lehet, írni nem!) triviálison (persze nem írható) és előre haladón túl: t=*x++; kimeneti “output” (csak írható) bizonyos szempontból a bemeneti ellentettje copy konstruktor érték megadása: *x=t; *x++=t; STL
31
Konstans (csak olvasható) iterátorok
konténer<típus>::const_iterator név; konstans függvényekben használandó utal arra, hogy a konténert csak olvassuk példa: ostream &operator<<(ostream&, const konténer<T>&); STL
32
Mire jó az, hogy funkcionális csoportokat definiálunk?
A könyvtári algoritmusok iterátorokkal érik el a konténereket viszont mindig csak bizonyos részeit használják az iterátorok funkcióinak (pl. összegzésnél: érték olvasása a=*x és előreléptetés ++x) Bevezethetünk saját konténert/iterátort, és hogy zökkenésmentes legyen ennek illesztése az algoritmusokhoz, ezek a funk. csoportok definiálják, milyen dolgokat kell az iterátorunknak teljesítenie. Ha saját algoritmust írunk, ami egy tárolót iterátorokon keresztül ér el, akkor ezekkel a tulajdonságokkal specifikálhatjuk, mit várunk el az iterátoroktól. STL
33
iterátorokkal kapcsolatos definíciók:
"utolsó utáni első" "érvényes" vagy elérhető az iterátor alatt tárolt érték, vagy "utolsó utáni első" "növelhető" definiált a ++x - "utolsó utáni első"-kre ez nem igaz j "elérhető" i-ből, ha véges ++i alkalmazása után fennáll i == j [i,j) olyan "intervallum"-ot jelöl, mely i-től j-ig (j bele nem értendő) terjed [i,j) akkor "érvényes intervallum", ha i és j is érvényes, valamint i-ből "elérhető" j STL
34
Asszociatív tömb (map)
Rendezett asszociatív tár, kulcs=>érték párokkal tulajdonságai: Az értékek nemcsak külső és belső find() függvénnyel, hanem operator[]-lel is elérhetőek (írásra és olvasásra) map1_demo.cc, map2_demo.cc Mivel rendezett tömbről van szó, a keresés/beszúrás/törlés O(log(n)) időben történik beszúrás történhet súgással (hint), így az O(log(n)) tovább rövidíthető STL
35
Asszociatív tömb (map)
A konténerben párokban vannak az adatok tárolva pair<kulcs,érték>, iterátor alól ezeket Key k=(*iter).first és Value v=(*iter).second -del tudjuk kinyerni. iterátor alatt a kulcs nem módosítható: (*iter).first=new_k nem működik - hiszen akkor máshova kerülne az adat a rendezett tömbben. két azonos kulcsú adat nem szerepelhet a tárolóban (erre a multimap lett kitalálva) Pl.: map3_demo.cc STL
36
Házi feladat - Lázgörbe
Statikus tömbök vektorrá alakítása + Vektorok elemeinek párosítása és map-be tétele + map kiírása az alábbi három tömbből készíts három vektort: int hour[]={6,8,14,23,18,16,21}; int min[]={11,22,33,44,55,31,41}; double dat[]={36.5,37.3,38.5,37.1,37.1,37.5,37.4}; definiáld a TimeStamp osztályt! Van benne kétparaméteres konstruktor (óra,perc) rendezési reláció (op<), ez const, és a paramétere is const &! friend kiírófv. (óra:perc) Töltsd fel a vektorokból a map<TimeStamp,double> konténert for ciklussal iteráljon végig egyszerre a vektorokon az órának és percnek megfelelő elemekből hozza létre a TimeStamp-et a map-be az adatokat op[] vagy insert() tagfv.-nyel is beteheted Írd ki a map tartalmát A megoldásban támaszkodj az előadás példaprogramjaira. STL
37
Halmaz (set) Elemek rendezett sora. Használjuk, ha:
az elemek beviteli sorrendjének nincs szerepe ha direkt azt szeretnénk, hogy a beviteli sorrendtől ftl. saját sorrendünk legyen gyakorta kell halmazműveleteket végezni gyakorta kell keresni az elemek között az egyediség garantálásával nem akarunk külön foglalkozni (automatikusan elvégzi) Pl.: set1_demo.cc, set2_demo.cc STL
38
rendezési reláció asszociatív konténerekben tárolt elemeket sorba kell tudni rendezni beépített típusokra ez működik pointerekre is (ami nekünk fejfájást is okozott – emlékezz: funktorok demói) osztályokra??? definiálni kell a bool operator<(const T&, const T&) függvényt. Pl. less1_demo.cc STL
39
rendezési reláció Mi van akkor, ha ettől eltérő sorrendben szeretnénk az adatokat tárolni? A sablon szerint: set<Key, Compare, Alloc> - tehát Compare: összehasonlítás megadható Hogyan? Típusa: less<T>, ami egy funktor Ennek egyetlen tagfüggvénye: bool operator()(const T& x, const T& y) alapból az operator<-t hívja meg ezt kell felüldefiniálni. Pl. less2_demo.cc STL
Hasonló előadás
© 2024 SlidePlayer.hu Inc.
All rights reserved.