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

Podobne dokumenty