Szablon klasy std::list
Transkrypt
Szablon klasy std::list
Szablon klasy std::list Bogdan Kreczmer ZPCiR IIAiR PWr pokój 307 budynek C3 [email protected] c 2006–2010 Bogdan Kreczmer? Copyright ° ? Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostepniony ˛ pod warun- kiem wykorzystania wyłacznie ˛ do własnych prywatnych potrzeb i może on być kopiowany wyłacznie ˛ w całości, razem z niniejsza˛ strona˛ tytułowa. ˛ Szablon klasy standardowej list lst.front( ) lst.back( ) – – zwraca pierwszy element, zwraca ostatni element, lst.push front(e) lst.pop front( ) lst.push back(e) lst.pop back( ) – – – – dodaje na poczatek ˛ kopie˛ elementu e, usuwa pierwszy element i nie zwraca go, dodaje na koniec kopie˛ elementu e, usuwa ostatni element i nie zwraca go, lst.size( ) lst.max size( ) – – zwraca aktualna˛ liczbe˛ elementów, zwraca najwieksz ˛ a˛ możliwa˛ ilość elementów jaka˛ można zaalokować, c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 1 Szablon klasy standardowej list lst.begin( ) lst.end( ) lst.rbegin( ) lst.rend( ) – – – – list<TYP>::iterator list<TYP>::const iterator – – zwraca iterator wskazujacy ˛ na pierwszy element, zwraca iterator wskazujacy ˛ na pozycje˛ za ostatnim elementem, zwraca iterator dla iteracji odwrotnej wskazujacy ˛ na ostatni element, zwraca iterator dla iteracji odwrotnej wskazujacy ˛ na pozycje˛ przed pierwszym elementem, typ iteratora mogacego ˛ wprowadzić zmiany w obiektach kolejki, typ iteratora nie mogacego ˛ wprowadzać zmian w obiektach kolejki. std::list<float> lst(6); for (std::list<float>::iterator iter = lst.begin(); iter != lst.end(); ++iter) ∗iter = 13; c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 2 Wzorzec listy dwukierunkowej std::list class Atrapa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . public: Atrapa( Atrapa const & ) { cout << ” == Konstruktor kopiujacy\n”; } Atrapa( ) { cout << ” ++ Konstruktor bezparametryczny\n”; } ∼ Atrapa( ) { cout << ” -- Destruktor \n”; } }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int main( ) { list <Atrapa> Lst; Atrapa A; cout << ” ## Przed ##########” << endl; Lst.push back(A); cout << ” ## Po #############” << endl; return 0; } Wynik działania: ++ Konstruktor bezparametryczny ## Przed ########## == Konstruktor kopiujacy ## Po ############# −− Destruktor −− Destruktor Elementy przekazywane do listy sa˛ kopiowane i ulegaja˛ destrukcji wraz z danym elementem listy. c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 3 Wzorzec listy dwukierunkowej std::list class Atrapa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . public: Atrapa( Atrapa const & ) { cout << ” == Konstruktor kopiujacy\n”; } Atrapa( ) { cout << ” ++ Konstruktor bezparametryczny\n”; } ∼ Atrapa( ) { cout << ” -- Destruktor \n”; } }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int main( ) { list <Atrapa∗> Lst; Atrapa A; cout << ” ## Przed ##########” << endl; Lst.push back(&A); cout << ” ## Po #############” << endl; return 0; Wynik działania: ++ Konstruktor bezparametryczny ## Przed ########## ## Po ############# −− Destruktor } Dla kolejki wskaźników na obiekty niszczenie elementów kolejki nie powoduje jednoczesnej destrukcji samych obiektów. c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 4 Usuwanie elementu class Atrapa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . public: Atrapa( Atrapa const & ) { cout << ” == Konstruktor kopiujacy\n”; } Atrapa( ) { cout << ” ++ Konstruktor bezparametryczny\n”; } virtual ∼ Atrapa( ) { cout << ” -- Destruktor \n”; } }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int main( ) { list <Atrapa> Lst; Atrapa A; cout << ” ## Przed ##########” << endl; Lst.push back(A); delete &Lst.front(); cout << ” ## Po #############” << endl; return 0; } Wynik działania: ++ Konstruktor bezparametryczny ## Przed ########## ++ Konstruktor kopiujacy −− Destruktor Segmentation fault ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ Samodzielne usuwanie elementu kolejki nie jest dopuszczalne. Operacje te musza˛ być realizowane za pośrednictwem zarzadcy. ˛ c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 5 Przegladanie ˛ listy struct Atrapa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int Numer; }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int main( ) { list <Atrapa> Lst; Lst.push back(Atrapa( )); Lst.push back(Atrapa( )); // Tworzymy liste˛ dwuelementowa˛ for (list<Atrapa>::iterator Iter = Lst.begin( ); Iter != Lst.end( ); ++Iter) { (∗Iter). Numer = 5; // Do tego elementu listy możemy odwołać sie˛ przez referencje˛ Iter–> Numer = 10; // lub wskaźnik. if ((∗Iter). Numer == 10) cout << "!!! Ten warunek jest spełniony." << endl; } } Iterator zapewnia bezpieczny dostep ˛ do wszystkich elementów listy. Postać warunku końca listy jest istotna, sposób inkrementacji operatora również. c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 6 Operacje na listach struct ProstaKlasa { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int Numer; bool operator < (ProstaKlasa const &Arg2) { return Numer < Arg2. Numer; } ProstaKlasa( int Num=0 ): Numer(Num) { } }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int main( ) { list <ProstaKlasa> Lst; Lst.push front(ProstaKlasa(5)); Lst.push front(ProstaKlasa(2)); Lst.push front(ProstaKlasa(7)); Lst.sort(); Lst.reverse(); // Sortowanie zgodnie z operatorem ’<’ // Odwrócenie porzadku ˛ while (!Lst.empty()) { cout << Lst.front(). Numer << endl; Lst.pop front(); // Usuwamy pierwszy element } } c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 7 Wykorzystanie listy struct Wektor 2f: public vector<float> { // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . float & x, & y; Wektor 2f( float x, float y ): vector<float>(2), x((∗this )[0]), y((∗this )[1]) { x = x; y = y; } }; // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . int main( ) { list<Wektor 2f> ObWielobok; ObWielobok.push back(Wektor 2f(3,5)); ObWielobok.push back(Wektor 2f(7,2)); ObWielobok.push back(Wektor 2f(5,10)); // Przegladanie ˛ w porzadku ˛ odwrotnym z możliwościa˛ zmian. for (list<Wektor 2f>::reverse iterator Iter = ObWielobok.rbegin(); Iter != ObWielobok.rend(); ++Iter ) { . . . } // Przegladanie ˛ w porzadku ˛ odwrotnym bez możliwości zmian. for (list<Wektor 2f>::const reverse iterator CIter = ObWielobok.rbegin(); CIter != (∗(const list<Wektor 2f >∗)&ObWielobok).rend(); ++CIter ) { . . . } } c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 8 Diagram klas dla przykładu z wielobokiem Diagram nie musi prezentować wszystkich zależności i szczegółów szablonów lub klas. Wystarcza˛ te na których chcemy skoncentorawać swoja˛ uwage. ˛ c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 9 Przykład zastosowania ograniczeń Ograniczenia i zwiazki ˛ moga˛ zachodzić miedzy ˛ różnymi klasami, jak też moga˛ one istnieć w obrebie ˛ jednej klasy. c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 10 Pytania i ćwiczenia 1. Dany jest fragment kodu: list< vector< double>> Lst(5); Lst.back()[1] = 5; (a) Czy prawda˛ jest, że powyższa instrukcja modyfikuje druga˛ współrz˛edna˛ wektora, który jest piatym ˛ elementem niniejszej listy? (b) Jeżeli nastepnym ˛ w kolejności jest polecenie: Lst.front().at(0) = 5; to jakim wynikiem sie˛ ono zakończy? 2. Dla jakich przypadków spełniona jest równość: Lst.begin() == Lst.rend() 3. Dany jest fragment kodu: list<double> Lst(5); double &Zm = Lst.back(); Zm = 5; Lst.push front(Lst.back()); Lst.pop back(); Zm = 9; (a) Jaka˛ wartość bedzie ˛ miał pierwszy element kolejki? (b) Czy przedstawiony fragment programu może spowodować bład ˛ krytyczny działania programu? Jeśli tak, to dlaczego? c 2006–2010 Bogdan Kreczmer Copyright ° Szablon klasy std::list 11