Esittely latautuu. Ole hyvä ja odota

Esittely latautuu. Ole hyvä ja odota

Sami Jantunen LTY/Tietotekniikan osasto

Samankaltaiset esitykset


Esitys aiheesta: "Sami Jantunen LTY/Tietotekniikan osasto"— Esityksen transkriptio:

1 Sami Jantunen LTY/Tietotekniikan osasto
Olio-ohjelmoinnin perusteet luento 7: C++ mallit, Standard Template Library (STL) Sami Jantunen LTY/Tietotekniikan osasto

2 Sisältö C++ mallit Standard Template Library (STL) Yhteenveto
Yleiskäyttöisyydestä Funktiomallit Luokkamallit Standard Template Library (STL) Taustaa Säiliöt Iteraattorit Yhteenveto

3 Yleiskäyttöisestä suunnittelusta
Oleellista on pystyä erottamaan pysyvät ja vaihtelevat asiat toisistaan! Halutaan uudelleenkäyttää pysyvät asiat ja johtaa uusia luokkia toteuttamalla erikseen vaihtelevat asiat Tavoitteelle löytyy oliopohjaisista kielista erilaisia mekanismeja Perintä on tyypillinen yleiskäyttöisyyteen liittyvä mekanismi Luokkien yhteiset ominaisuudet voidaan toteuttaa kertalleen kantaluokassa. Vaihtuvat asiat toteutetaan lapsiluokissa Perinnän käytöllä on kuitenkin rajansa!

4 Perinnän rajoituksia yleiskäytettävyydessä
Aliluokat perivät kantaluokkansa rajapinnan ja toteutuksen kokonaisuudessaan ja täsmälleen samanlaisena! Pysyvään osuutteen kuuluu siis kokonaisia palveluita (jäsenfunktioita) parametreineen ja paluuvarvoineen. Todellinen tarve ei kuitenkaan aina ole tällainen!

5 Muistatko vielä? (IntDeque)
Otetaanpa Deque luokka hyötykäyttöön! Luodaan Int-pohjainen lista IntDeque void goBeforeFirst(); void goAfterLast(); void forth(); void back(); int isBeforeFirst() const; int isAfterLast() const; IntDeque(); void insert (int); void remove(); int current () const; ~IntDeque(); class IntDeque: public Deque { public: IntDeque(); void insert (int); void remove(); int current () const; ~IntDeque(); }; Deque-luokasta peritty Uusi toiminnallisuus next prev data next prev data next prev data

6 Esimerkki: 2-suuntainen lista
Pysyvä osa: Listan toteutus (alkioiden käsittely) Vaihtuva osa: Alkioiden tyyppi Perinnän käyttö ei kovin kätevää! Useat rajapinnoista on kuitenkin riippuvaisia alkion tyypistä. Uudelleenkäytettävyyden taso heikkenee Deque IntDeque DoubleDeque Muistathan vielä 2-suuntaisen listaesimerkkimme?

7 Entäpä jos? Mitä jos vaatisimme, että eri tyyppiset alkiot perittäisiin samasta kantaluokasta? Sama 2-suuntainen listatoteutus toimisi riippumatta alkion todellisesta tyypistä Deque Alkio IntAlkio DoubleAlkio

8 Ratkaisun huonoja puolia
Tyyppitietoisuus häviää Listaan on mahdollista tallettaa eri tyyppejä sekaisin Kääntäjä ei pysty tekemään tyyppitarkistuksia Taulukon käyttäjän tulee itse tietää mitä tyyppiä alkiot oikeasti on (ja tehdä tarvittaessa osoittimen muunnostyöt) Deque Alkio IntAlkio DoubleAlkio

9 Johtopäätös Erityyppisillä taulukoilla on todella paljon yhteistä
Yhteiset asiat on kuitenkin sen luonteisia, että niitä on vaikea toteuttaa yleiskäyttöiseksi kantaluokkaan Taulukon alkioiden tyyppi vaikuttaa taulukon rajapintaan ja toteutukseen kauttaaltaan Alkioiden tyyppien erilaisuuden merkitystä ei voi eliminoida ilman, että tingitään tyyppiturvallisuudesta ja käyttömukavuudesta Olisi kiva jos olisi muitakin mekanismeja pysyvyyden ja vaihtelevuuden hallintaan

10 C++ Mallit (Templates)
Käännösaikaisesti tyypitetyissä kielissä (kuten C++) täytyy kaikkien parametrien ja muuttujien tyyppien olla selvillä jo ohjelmaa käännettäessä. Tyyppien geneerisyys ei onnistu ilman lisäkikkoja Mallit (template) ovat C++:n tapa kirjoittaa yleiskäyttöisiä: funktioita (funktiomallit, function templates) luokkia (Luokkamallit, class templates) Malleissa tyyppejä ja joitain muitakin asioita voidaan jättää määrämäättä Auki jätetyt asiat “sidotaan” vasta myöhemmin käytön yhteydessä. Näin saadaan säilytettyä C++:n vahva käännösaikainen tyypitys, mutta annetaan silti mahdollisuus kirjoittaa geneeristä koodia

11 Esimerkki C++ mallista
Otetaan esimerkiksi meidän 2-suuntainen lista Muutetaan olemassa olevaa toteutusta ja käytetään perinnän sijasta luokkamallia Toteutetaan Deque-malliin yleinen toiminnallisuus Jätetään alkioiden tyyppi vielä määrittelemättä Kun lista otetaan käyttöön, määritellään samalla alkioiden tyyppi tyyliin: Deque <int> Deque <double> Auki jätetyt asiat siis selviävät jo käännösaikana, mutta kuitenkin vasta vektoreiden käyttötilanteessa Deque

12 C++ mallin syntaksi Malli alkaa avainsanalla template
template<typename tyyppiparam1, typename tyyppiparam2, ...> //Tähän normaali funktion tai luokan määrittely TAI template<class tyyppiparam1, class tyyppiparam2, ...> Malli alkaa avainsanalla template Seuraavaksi esitellään kulmasulkeiden sisällä kaikki auki jätetyt tyyppiparametrit Tämän jälkeen seuraa itse mallin koodi (normaalin funktion tai luokan tapaan) Tyyppiparametreja voi käyttää koodissa aivan kuin normaaleja C++ tyyppejä.

13 Funktiomallit (function template)
Geneerisiä malleja, joista kääntäjä voi generoida eri tyypeillä toimivia funktioita Kääntäjä osaa automaattisesti päätellä kutsusta tyyppiparametrien arvot Voidaan kutsua aivan kuin mitä tahansa muuta funktiota: min(1,2); //int min(2.3, 5.7); //double On myös mahdollista eksplisiittesesti määrätä tyyppiparametreille arvot: float f = min<float>(3.2,6) template <typename T> //Tai template <class T> T min(T p1, T p2) { T tulos; if (p1 < p2) tulos = p1; } else tulos = p2; return tulos

14 Luokkamallit (class template)
template <typename T1, typename T2> class Pari { public: Pari(T1 eka, T2 toka); T1 annaEka() const; T2 annaToka() const; . private T1 eka_; T2 toka_; }; Toimii mallina luokille, jotka ovat muuten samanlaisia, mutta joissa jotkin tyypit voit erota toisistaan Esimerkkinä vieressä oleva malli Pari: Ei oma luokkansa vaan malli kokonaiselle “perheelle” luokkia Kaksi auki jätettyä tyyppiä T1 ja T2 Luokat saadaan luotua määräämällä tyyppiparametreille arvot. Esimerkki: Pari<int,double> p(1, 3.2); template <typename T1, typename T2> Pari<T1, T2>::Pari(T1 eka, T2 toka) :eka_(eka), toka_(toka) { } T1 Pari<T1, T2>::annaEka() const return eka_;

15 Ajattelumalli, joka toivottavasti helpottaa luokkamallin käyttöä:
luokan tyyppi luotava olio Pari<int,double> p(1, 3.2); Yllä olevassa esimerkissä Pari<int,double> voidaan käsittää luokan tyyppinä (aivan kuin luokan tyypit myString tai myVeryOwnClass) void f(Pari<int,int> &i, Pari<float, int*> d); ihan tavallinen funktio jolla on kaksi täysin eri tyyppistä luokkaa parametrina int,int -pari float, int* -pari luokan tyyppi luokan tyyppi

16 Tyyppiparametreille asetetut vaatimukset
C++ mallin koodin on käännyttävä, kun tyyppiparametrien tilalle sijoitetaan todelliset tyypit esimerkiksi aiemmin määrittelemämme min –funktiomallin parametrit pitää olla sellaisia, että niiden arvoja voi vertailla < operaattorilla Jos mallin koodi kutsuu auki jätetyn tyypin kautta esim. olion jäsenfunktiota, voi mallia käyttää vain sellaisten tyyppien kanssa, mistä kyseinen jäsenfunktio löytyy

17 Mallien parametreista
Malleilla voi olla oletusparametreja template<typename T1 = int, typename T2 = T1> Malleilla voi olla vakioparametreja template<unsigned long SIZE> class Mjono { public: Mjono(const char *arvo); const char* annaArvo() const; private: char taulukko[SIZE+1]; }; Mjono<12> s1(“Tuli täyteen”);

18 Mallien erikoistus On mahdollista määrittää erityinen versio (juuri tietyille tyypeille) mallista: template <> class Pari<bool, bool> { public: Pari(bool eka, bool toka); bool annaEka() const; bool annaToka() const; . private: unsigned char ekaJaToka_; }; bool Pari<bool, bool>::annaEka() const return (ekaJaToka_ & 1) != 0; } Tyhjät kulmasulkeet merkiksi siitä, että erikoistumisessa ei ole enään auki jääneitä tyyppejä Kirjoitettu auki ne tyypit mitä erikoistumiinen koskee

19 Missä mennään? C++ mallit Standard Template Library (STL) Yhteenveto
Yleiskäyttöisyydestä Funktiomallit Luokkamallit Standard Template Library (STL) Taustaa Säiliöt Iteraattorit Yhteenveto

20 STL (Standard Template Library)
Hyvä esimerkki C++ mallien käytöstä ja geenrisestä ohjelmoinnista Määrittelee joukon tavallisimpia tietorakenteita ja niiden käyttöön tarkoitettuja algoritmeja Tarkoituksena on uudelleen käyttää STL:n optimoituja tietorakenteita sen sijaan, että “keksittäisiin pyörä uudelleen”

21 STL:n rakenne Säiliöt (container) ovat STL:n tarjoamia tietorakenteita
Iteraattorit (iterator) ovat “kirjanmerkkejä” säiliöiden läpikäymiseen Geneeriset algoritmit (generic algorithm) käsittelevät säiliöitä iteraattoreiden avulla Säiliösovittimet (container adaptor) ovat säiliömalleja, jotka toteutetaan halutun toisen säilion avulla. Niillä voi muuntaa säiliön rajapinnan toisenlaiseksi Funktio-oliot (function object) ovat olioita, jotka käyttäytyvät kuten funktiot ja joita voi käyttää muun muassa algoritmien toiminnan säätämiseen Varaimet (allocator) oava olioita säiliöivien muistinhallinnan räätälöintiin. Lyhyesti selitettynä varaimet ovat olioita, jotka osaavat varata ja vapauttaa muistia. Normaalisti STL:n säiliöt varaavat muistinsa new’llä ja vapauttavat deletellä. Jos niille annetaan ylimääräisenä tyyppiparametrina varainluokka, ne käyttävät ko.luokan palveluita tarvitsemansa muistin varaamiseen ja vapauttamiseen

22 STL Algoritmien geneerisyys
Olemme olio-ohjelmoijina tottuneet siihen, että halutut tiedot ja toiminnallisuudet kirjoitetaan luokan jäsenfunktioihin. Tuntuisi siis loogiselta, että STL:n tarjoamat algoritmit olisi myös toteutettu säiliöiden jäsenfunktiona STL:ssä lähes kaikki algoritmit on kuitenkin kirjoitettu irrallisina funktioina. Miksi? algoritmien geneerisyys on laajempaa kuin pelkkä tyypin auki jättäminen tyypin lisäksi STL:n algoritmit jättävät mm. auki sen minkä tietorakenteen kanssa ne toimivat. näin samaa geneeristä find-algoritmia voidaan käyttää niin listan, vektorin kuin joukonkin kanssa. algoritmiä ei myöskään tarvitse kirjoittaa erikseen jokaiselle säiliölle vaan yksi geneerinen funktiomalli toimii kaikkien säiliöiden kanssa geneerisyydestä seuraa myös se, että STL:n algoritmeja voi käyttää myös omien tietorakenteiden kanssa (kunhan ne vain toteuttavat STL:n algoritmien asettamat vaatimukset)

23 STL:n säiliöt STL:n säiliöt muistuttavat suuresti toisiaan
Säiliöt jakautuvat pääpiirteittään kahteen kategoriaan: Sarjat (sequence) ovat säiliöitä, joiden alkioita pystyy hakemaan niiden järjestysnumeron perusteella. Samoin alkioita voi lisätä haluttuun paikkaan ja poistaa siitä. Esimerkki: vector Assosiatiiviset säiliöt (associative container) puolestaan perustuvat siihen, että alkioita haetaan säiliöstä avaimen (key) perusteella. Esimerkiksi puhelinluettelo muistuttaa assosiatiivista säiliötä– siinä numeron pystyy etsimään nopeasti nimen perusteella

24 Säiliöiden käyttöohjeet Esim. Visual C++ online help

25 STL:n alkioista Alkioiden tyypeillä tulee olla:
kopiorakentaja, joka luo alkuperäisen olion kanssa samanlaisen olion sijoitusoperaattori, jonka tuloksena sijoituksen kohteena olevasta oliosta tulee samanlainen sijoitetun olion kanssa STL:n assosiatiiviset säiliöt vaativat, että alkioiden avaimia voi myös kopioida ja sijoitaa ja lisäksi kahta avainta täytyy pystyä vertailemaan Viitteet eivät kelpaa alkioiksi

26 Sarjat-”peräkkäissäiliöt”
Sarjat ovat säiliöitä, joissa alkiot sijaitsevat “peräkkäin” ja joissa jokaisella alkiolla on järjestysnumero Alkioita voi selata järjestyksessä Halutun alkion voi hakea järjestysnumeron perusteella Uusia alkioita voi lisätä säiliössä haluttuun paikkaan ja vanhoja voi poistaa STL:n sarjasäiliöt: vector deque list Kaikissasarjoissa annetaan sarjan alkioiden tyyppi mallin tyyppiparametrina. Esim: vector<float>, deque<int> ja list<string>

27 Vector esimerkki (1/3) Sample Code:
////////////////////////////////////////////////////////////////////// // // Compile options needed: /GX // front.cpp: Illustrates the vector::front and vector::back methods. // Functions: // vector::front - Returns reference to first element of vector. // vector::back - Returns reference to last element of vector. // vector::push_back - Appends (inserts) an element to the end of a // vector, allocating memory for it if necessary. // vector::size - Returns number of elements in the vector. // vector::begin - Returns an iterator to start traversal of the vector. // vector::end - Returns an iterator for the last element of the vector. // vector::erase - Deletes elements from a vector (single & range).

28 Vector esimerkki (2/3) cout << "First element: " << theVector.front() << endl; cout << "Last element: " << theVector.back() << endl; cout << "Elements in vector: " << theVector.size() << endl; // Delete the last element of the vector. Remember that the vector // is 0-based, so theVector.end() actually points 1 element beyond // the end. theVector.erase(theVector.end() - 1); cout << endl << "After erasing last element, new last element is: " << theVector.back() << endl; // Delete the first element of the vector. theVector.erase(theVector.begin()); cout << "After erasing first element, new first element is: " << theVector.front() << endl; } // The debugger can't handle symbols more than 255 characters // long. STL often creates symbols longer than that. When //symbols are longer than 255 characters, the warning is issued. #pragma warning(disable:4786) #include <iostream> #include <vector> using namespace std ; typedef vector<int> INTVECTOR; const ARRAY_SIZE = 4; void main() { // Dynamically allocated vector begins with 0 elements. INTVECTOR theVector; // Intialize the array to contain the members [100, 200, 300, 400] for (int cEachItem = 0; cEachItem < ARRAY_SIZE; cEachItem++) theVector.push_back((cEachItem + 1) * 100);

29 Vector esimerkki (3/3) Program Output is: =====================
First element: 100 Last element: 400 Elements in vector: 4 After erasing last element, new last element is: 300 After erasing first element, new first element is: 200 Elements in vector: 2

30 Deque esimerkki (1/3) Sample Code:
////////////////////////////////////////////////////////////////////// // // Compile options needed: -GX // deque.cpp : // Functions: // operator[] // at // empty // push_back // begin // end

31 Deque esimerkki (2/3) //print out the contents print_contents (a,"a");
cout <<"The first element of a is " <<a[0] <<endl; cout <<"The first element of a is " <<a.at(0) <<endl; cout <<"The last element of a is " <<a[a.size()-1] <<endl; cout <<"The last element of a is " <<a.at(a.size()-1) <<endl; } //function to print the contents of deque void print_contents (CHARDEQUE deque, char *name) { CHARDEQUE::iterator pdeque; cout <<"The contents of "<< name <<" : "; for(pdeque = deque.begin(); pdeque != deque.end(); pdeque++) cout << *pdeque <<" " ; cout<<endl; /* Compile options needed:-GX */ #include <iostream> #include <deque> using namespace std; typedef deque<char > CHARDEQUE; void print_contents (CHARDEQUE deque, char*); void main() { //create an empty deque a CHARDEQUE a; //check whether it is empty if(a.empty()) cout<<"a is empty"<<endl; else cout<<"a is not empty"<<endl; //inset A, B, C and D to a a.push_back('A'); a.push_back('B'); a.push_back('C'); a.push_back('D'); //check again whether a is empty

32 Deque esimerkki (3/3) Program Output is: =============== a is empty
a is not empty The contents of a : A B C D The first element of a is A The last element of a is D

33 list esimerkki (1/3) Sample Code:
////////////////////////////////////////////////////////////////////// // // Compile options needed: -GX // assign.cpp : Shows the various ways to assign and erase elements // from a list<T>. // Functions: // list::assign // list::empty // list::erase

34 list esimerkki (2/3) // 1 2 3 for (i = listAnother.begin(); i != listAnother.end(); ++i) cout << *i << " "; cout << endl; listAnother.assign(4, 1); // listAnother.erase(listAnother.begin()); // 1 1 1 listAnother.erase(listAnother.begin(), listAnother.end()); if (listAnother.empty()) cout << "All gone\n"; } #include <list> #include <iostream> using namespace std ; typedef list<int> LISTINT; void main() { LISTINT listOne; LISTINT listAnother; LISTINT::iterator i; // Add some data listOne.push_front (2); listOne.push_front (1); listOne.push_back (3); listAnother.push_front(4); listAnother.assign(listOne.begin(), listOne.end());

35 list esimerkki (3/3) Program Output is: 1 2 3 1 1 1 All gone

36 Assosiatiiviset säiliöt (associative container)
Eroavat sarjoista siinä, että alkioita ei lueta, lisätä tai poisteta niiden “sijainnin” tai järjestysnumeron perusteella Jokaiseen alkioon liittyy avain (key), jonka perusteella alkion voi myöhemmin hakea

37 Assosiatiiviset säiliötyypit
Yksinkertaisin säiliötyyppi, missä avaimena on alkio itsessään multiset Eroaa setistä siten, että samanarvoisia alkioita voi olla useita map Tietorakenne, missä avain ja alkio ovat erillisiä ja jossa avaimen perusteella voidaan hakea haluttu alkio. Voidaan myös ajatella eräänlaisena taulukkona multimap Eroaa mapista siten, että yhtä avainta kohde voi olla useita alkioita

38 set esimerkki (1/3) ////////////////////////////////////////////////////////////////////// // // Compile options needed: -GX // SetFind.cpp: // Illustrates how to use the find function to get an iterator // that points to the first element in the controlled sequence // that has a particular sort key. // Functions: // find Returns an iterator that points to the first element // in the controlled sequence that has the same sort key // as the value passed to the find function. If no such // element exists, the iterator equals end().

39 set esimerkki (2/3) void main() { SET_INT s1;
cout << "s1.insert(5)" << endl; s1.insert(5); cout << "s1.insert(8)" << endl; s1.insert(8); cout << "s1.insert(12)" << endl; s1.insert(12); SET_INT::iterator it; cout << "it=find(8)" << endl; it=s1.find(8); cout << "it!=s1.end() returned "; truefalse(it!=s1.end()); // True cout << "it=find(6)" << endl; it=s1.find(6); truefalse(it!=s1.end()); // False } #pragma warning(disable:4786) #include <set> #include <iostream> using namespace std ; typedef set<int> SET_INT; void truefalse(int x) { cout << (x?"True":"False") << endl; }

40 set esimerkki (3/3) Program Output is: ============= s1.insert(5)
it=find(8) it!=s1.end() returned True it=find(6) it!=s1.end() returned False

41 map esimerkki (1/3) Sample Code:
////////////////////////////////////////////////////////////////////// // // Compile options needed: None // <filename> : main.cpp // Functions: // end // find // insert

42 map esimerkki (2/3) #pragma warning(disable:4786)
#include <iostream> #include <string> #include <map> using namespace std; typedef map<int, string, less<int> > INT2STRING; void main() { // 1. Create a map of ints to strings INT2STRING theMap; INT2STRING::iterator theIterator; string theString = ""; int index; // Fill it with the digits 0 - 9, each mapped to its string counterpart // Note: value_type is a pair for maps... theMap.insert(INT2STRING::value_type(0,"Zero")); theMap.insert(INT2STRING::value_type(1,"One")); theMap.insert(INT2STRING::value_type(2,"Two")); theMap.insert(INT2STRING::value_type(3,"Three")); theMap.insert(INT2STRING::value_type(4,"Four")); theMap.insert(INT2STRING::value_type(5,"Five")); theMap.insert(INT2STRING::value_type(6,"Six")); theMap.insert(INT2STRING::value_type(7,"Seven")); theMap.insert(INT2STRING::value_type(8,"Eight")); theMap.insert(INT2STRING::value_type(9,"Nine")); // Read a Number from the user and print it back as words for( ; ; ) { cout << "Enter \"q\" to quit, or enter a Number: "; cin >> theString; if(theString == "q") break; // extract each digit from the string, find its corresponding // entry in the map (the word equivalent) and print it for(index = 0; index < theString.length(); index++){ theIterator = theMap.find(theString[index] - '0'); if(theIterator != theMap.end() ) // is 0 - 9 cout << (*theIterator).second << " "; else // some character other than 0 - 9 cout << "[err] "; } cout << endl;

43 map esimerkki (3/3) Program Output is: ==============
Enter "q" to quit, or enter a Number: 22 Two Two Enter "q" to quit, or enter a Number: 33 Three Three Enter "q" to quit, or enter a Number: 456 Four Five Six Enter "q" to quit, or enter a Number: q

44 Iteraattorit On hyvin tavallista, että tietorakenteen alkioita käydään läpi järjestyksessä yksi kerrallaan Tyypillinen ratkaisuyritys ongelmaan on lisätä läpikäymiseen tarvittavat operaatiot itse tietorakenteeseen annaEnsimmainen annaSeuraava onkoLoppu Tällöin säiliö muistaisi itse, missä alkiossa läpikäyminen on sillä hetkellä menossa

45 Iteraattorit Edellä ehdotetun ratkaisumallin ongelmat ovat:
säiliön tila koostuisi sekä listan alkioista että läpikäyntipaikasta. operaatiot kuten annaEnsimmainen() ja annaSeuraavat() muuttaisivat väistämättä säiliön tilaa kyseiset operaatiot eivät voisi olla vakiojäsenfunktioita vakioviitteen päässä olevaa listaa ei voisi täten selata läpi Usein on tarve lukea listaa kahdesta kohtaan yhtä aikaa.

46 Iterator Luodaan kaksi eri luokkaa
varsinainen säiliö, joka ei sisällä mitään paikkatietoa “kirjanmerkki”, joka vaan muistaa, missä kohtaa säiliötä ollaan läpikäymässä Kyseessä on tunnettu Design Pattern (Iterator)

47 Iteraattorit Erittäin tärkeä käsite STL:ssä
Jokaista säiliötyyppiä kohden on olemassa myös iteraattorityyppi, jonka avulla säiliön alkiot voi käydä läpi Iteraatorin voi käsittää kirjainmerkkinä, joka muistaa tietyn paikan tietyssä säiliössä. iteraattoria voi siirrellä säiliön sisällä iteraattorin läpi voi lukea ja muuttaa säiliön alkioita

48 Iteraattorikategorioita
syöttöiteraattori (input iterator) voi vain lukea alkioita tulostusiteraattori (output iterator) voi vain muuttaa alkioita (ei lukea) eteenpäin-iteraattori (forward iterator) voi lukea ja muuttaa alkioita ja lisäksi iteraattoria voi siirtää yhdellä eteenpäin. kaksisuuntainen iteraattori (bidirectional iterator) voi lukea, muuttaa ja liikkua kumpaakin suuntaan hajasaanti-iteraattori (random access iterator) on kuin kaksisuuntainen iteraattori, mutta se voi harpata mielivaltaisia askelia.

49 iterator & map esimerkki
#pragma warning(disable:4786) #include <iostream> #include <string> #include <map> using namespace std ; typedef map<string, int> STRING2INT; void main() { STRING2INT MyMap; STRING2INT::iterator MyIterator; string MyBuffer; // Fill in MyMap with the months of the year, mapped to their number // January - 1, February - 2, etc. using operator[]. MyMap["January"] = 1; MyMap["February"] = 2; . // Ask the user for a month of the year and print the number // that corresponds to the month entered //MyIterator = MyMap.end(); while(MyIterator == MyMap.end()){ cout << "Enter a Month :"; cin >> MyBuffer; if((MyIterator = MyMap.find(MyBuffer)) != MyMap.end()) cout << (*MyIterator).first << " is Month Number " << (*MyIterator).second << endl; else cout << "Enter a Valid Month (example: March)" << endl; }

50 iteraattoreiden kelvollisuus
jos säiliöön lisätään tai siitä poistetaan alkioita, olemassa olevat iteraattorit muuttuvat käkyttökelvottomaksi tällöin iteraattori tulee määritellä uudestaan

51 STL algoritmit & funktio-oliot
STL algoritmit ja funktio-oliot ovat vielä käsittelemättä ne suljetaan tällä kertaa kurssin ulkopuolelle.

52 Mitä tänään opimme? Haluamme tehdä geneeristä koodia.
Valitettavasti perintä ei aina ratkaise pulmiamme. Joissain tilanteissa C++ mallien käyttö on hyvä työkalu geneerisyyteen C++ malleja on sekä luokka- että funktiomallit Standard Template Library (STL) Hyvä esimerkki siitä miten C++ mallien avulla saadaan geneeristä koodia STL sisältää Säiliötä Iteraattoreita Algoritmeja Funktio-oliota

53 Tentistä Pyritään kattamaan koko tenttialue Paljon kysymyksiä
Oleellista ei ole “muistaa” pikkudetaljeja Pyritään varmistamaan, että oleellisimmat asiat on YMMÄRRETTY!


Lataa ppt "Sami Jantunen LTY/Tietotekniikan osasto"

Samankaltaiset esitykset


Iklan oleh Google