Szablon klasy std::list Bogdan Kreczmer ZPCiR IIAiR PWr pokój 307 budynek C3 bogdan.kreczmer@pwr.wroc.pl Copyright c 2006 2010 Bogdan Kreczmer Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostępniony pod warunkiem 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( ) zwraca pierwszy element, lst.back( ) zwraca ostatni element, lst.push front(e) dodaje na poczatek kopię elementu e, lst.pop front( ) usuwa pierwszy element i nie zwraca go, lst.push back(e) dodaje na koniec kopię elementu e, lst.pop back( ) usuwa ostatni element i nie zwraca go, lst.size( ) zwraca aktualna liczbę elementów, lst.max size( ) zwraca największa możliwa ilość elementów jaka można zaalokować, Copyright c 2006 2010 Bogdan Kreczmer Szablon klasy std::list 1
Szablon klasy standardowej list lst.begin( ) zwraca iterator wskazujacy na pierwszy element, lst.end( ) zwraca iterator wskazujacy na pozycję za ostatnim elementem, lst.rbegin( ) zwraca iterator dla iteracji odwrotnej wskazujacy na ostatni element, lst.rend( ) zwraca iterator dla iteracji odwrotnej wskazujacy na pozycję przed pierwszym elementem, list<typ>::iterator typ iteratora mogacego wprowadzić zmiany w obiektach kolejki, list<typ>::const iterator 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; Copyright c 2006 2010 Bogdan Kreczmer 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. Copyright c 2006 2010 Bogdan Kreczmer 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. Copyright c 2006 2010 Bogdan Kreczmer 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. Copyright c 2006 2010 Bogdan Kreczmer 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 listę dwuelementowa for (list<atrapa>::iterator Iter = Lst.begin( ); Iter!= Lst.end( ); ++Iter) { ( Iter). Numer = 5; // Do tego elementu listy możemy odwołać się przez referencję Iter > Numer = 10; // lub wskaźnik. if (( Iter). Numer == 10) cout << "!!! Ten warunek jest spełniony." << endl; Iterator zapewnia bezpieczny dostęp do wszystkich elementów listy. Postać warunku końca listy jest istotna, sposób inkrementacji operatora również. Copyright c 2006 2010 Bogdan Kreczmer 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(); // Sortowanie zgodnie z operatorem < Lst.reverse(); // Odwrócenie porzadku while (!Lst.empty()) { cout << Lst.front(). Numer << endl; Lst.pop front(); // Usuwamy pierwszy element Copyright c 2006 2010 Bogdan Kreczmer 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 ) {... Copyright c 2006 2010 Bogdan Kreczmer 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 uwagę. Copyright c 2006 2010 Bogdan Kreczmer Szablon klasy std::list 9
Przykład zastosowania ograniczeń Ograniczenia i zwiazki moga zachodzić między różnymi klasami, jak też moga one istnieć w obrębie jednej klasy. Copyright c 2006 2010 Bogdan Kreczmer 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ędna wektora, który jest piatym elementem niniejszej listy? (b) Jeżeli następnym w kolejności jest polecenie: Lst.front().at(0) = 5; to jakim wynikiem się 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ść będzie miał pierwszy element kolejki? (b) Czy przedstawiony fragment programu może spowodować bład krytyczny działania programu? Jeśli tak, to dlaczego? Copyright c 2006 2010 Bogdan Kreczmer Szablon klasy std::list 11