c++ wykład 11 (30.05.2013)
DESCRIPTION
C++ wykład 11 (30.05.2013). Własne biblioteki, standardowa biblioteka szablonów STL. Kompilacja i łączenie. Plik jako jednostka kompilacji. Preprocesing – obsługa makr i dyrektyw włączających – dostarcza kompilatorowi jednostkę translacji. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/1.jpg)
C++wykład 11 (30.05.2013)
Własne biblioteki, standardowa biblioteka
szablonów STL
![Page 2: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/2.jpg)
Kompilacja i łączenie Plik jako jednostka kompilacji. Preprocesing – obsługa makr i dyrektyw
włączających – dostarcza kompilatorowi jednostkę translacji.
Kompilator analizuje jednostkę translacji w izolacji od reszty programu.
Fizyczna struktura programu (podział na pliki) powinna wynikać z logicznej struktury programu.
Rola linkera przy budowaniu programu albo biblioteki.
![Page 3: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/3.jpg)
Moduły Każdy większy program składa się z pewnej
liczby oddzielnych części – modułów. Moduł to kompletny fragment programu
(moduł obliczeniowy, moduł we/wy, moduł prezentacji, itp).
Podział kodu na moduły porządkuje logikę programu.
Należy minimalizować zależności między modułami.
![Page 4: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/4.jpg)
Biblioteki Moduły, z których może korzystać wiele programów
umieszcza się w oddzielnych skompilowanych plikach, zwanych bibliotekami.
Typy bibliotek w C++: biblioteka statyczna jest dołączana do programu
wynikowego na etapie linkowania; biblioteka współdzielona jest dołączana do programu w
trakcie ładowania programu do pamięci; biblioteka dynamiczna jest dołączana do uruchomionego
procesu w trakcie działania programu.
![Page 5: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/5.jpg)
Biblioteki Biblioteka to zbiór klas, funkcji i zmiennych, z
których mogą korzystać różne programy. Biblioteka ma postać binarną – jej
poszczególne fragmenty są skompilowane (biblioteka jest kolekcją plików obiektowych).
Korzystanie z bibliotek ułatwia programowanie (korzystamy z gotowych i sprawdzonych fragmentów kodu) i przyspiesza proces rekompilacji.
![Page 6: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/6.jpg)
Biblioteki Wynikiem samej kompilacji pliku źródłowego
(plik.c albo plik.cpp) jest plik plik.o pod Linuxem albo plik.obj pod Windowsem.
Biblioteki statyczne mają nazwy libmodul.a pod Linuxem albo modul.lib pod Windowsem.
Biblioteki dynamiczne mają nazwy libmodul.so pod Linuxem (tak jak biblioteki współdzielone) albo modul.dll pod Windowsem.
![Page 7: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/7.jpg)
Biblioteka statyczna Używając biblioteki statycznej przekazujemy jej
archiwum linkerowi w czasie kompilacji. Linker wyszukuje w nim tylko tych plików obiektowych, które są niezbędne do działania naszego programu i kopiuje je bezpośrednio do programu.
Program wynikowy korzystający z biblioteki statycznej jest obszerniejszy ale szybciej się ładuje do pamięci.
Program wynikowy zlinkowany z biblioteką statyczną jest niezależny od plików zewnętrznych.
Uaktualnienie biblioteki wymaga rekompilacji programu.
![Page 8: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/8.jpg)
Biblioteka statycznalib.cpp
lib.o
static library
prog.cpp
prog.o
a.out
memory
linker
loader
g++ar
g++
g++
ssh
![Page 9: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/9.jpg)
Biblioteka współdzielona Programy korzystające biblioteki współdzielonej nie
zawierają bezpośrednio kodu z tej biblioteki a tylko referencję do niej.
Program wynikowy korzystający z biblioteki współdzielonej jest chudszy ale wolniej ładuje się do pamięci (biblioteki współdzielone są odszukiwane i ładowane do pamięci razem z programem).
Program wynikowy skompilowany z biblioteką współdzieloną jest zależny od plików zewnętrznych.
Zmodyfikowanie biblioteki współdzielonej spowoduje zmianę w działaniu programu ale bez jego ponownej kompilacji.
![Page 10: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/10.jpg)
Biblioteka współdzielona
lib.cpp
lib.o
shared library
prog.cpp
prog.o
a.out
memory
linker
loader
g++
g++
g++
g++
ssh
![Page 11: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/11.jpg)
Biblioteka dynamiczna Programy korzystające bibliotek dynamicznych nie
zawierają bezpośrednio kodu z tej biblioteki ale muszą korzystać ze specjalnych metod włączania takich bibliotek w trakcie działania programu (plik nagłówkowy <dlfcn.h>).
Program wynikowy korzystający z biblioteki dynamicznej jest chudszy i szybciej ładuje się do pamięci, ale działa wolniej (biblioteki dynamiczne można załadować w dowolnym momencie w trakcie działania programu).
Program wynikowy skompilowany z biblioteką dynamiczną jest zależny od plików zewnętrznych.
Zmodyfikowanie biblioteki dynamicznej spowoduje zmianę w działaniu programu ale bez jego ponownej kompilacji.
![Page 12: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/12.jpg)
Biblioteka dynamiczna
lib.cpp
lib.o
dynamic library
prog.cpp
prog.o
a.out
memory
linker
loader
g++
g++
g++
g++
ssha.out
![Page 13: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/13.jpg)
Tworzenie bibliotek (pod Linuxem)Tworzenie programu bez dołączanych bibliotek.
Załóżmy, że mamy pliki src1.cpp, src2.cpp i src3.cpp, które stanowią moduł obliczeniowy oraz plik prog.cpp, który będzie korzystał z funkcji i klas zdefiniowanych w module obliczeniowym.
Aby skompilować cały program razem z modułem obliczeniowym należy wydać polecenie:$ g++ -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp prog.cpp -o calculation
Aby skompilować cały program razem z modułem obliczeniowym i statycznie zlinkować z innymi bibliotekami (rozmiar programu wynikowego będzie znacznie większy) należy wydać polecenie:$ g++ -static …
Aby uruchomić skompilowany program należy wydać polecenie:$ ./calculation
Aby sprawdzić z jakimi bibliotekami jest linkowany program i jakie symbole są w nim użyte należy wydać polecenie:$ ldd calculation$ nm calculation
![Page 14: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/14.jpg)
Tworzenie bibliotek (pod Linuxem)Program korzystający z biblioteki statycznej.
Najpierw kompilujemy pliki źródłowe do plików obiektowych:$ g++ -c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp
Następnie łączymy pliki obiektowe do jednego pliku bibliotecznego libsrc.a:$ ar crs libsrc.a src1.o src2.o src3.o
Na koniec należy skompilować plik z programem i zlinkować go z biblioteką:$ g++ -c -Wall -ansi -pedantic prog.cpp$ g++ -o calculation prog.o –L. –lsrc
Teraz można uruchomić skompilowany program:$ ./calculation
Wyjaśnienie: opcja -Lścieżka określa ścieżkę do biblioteki, opcja -lbiblioteka określa nazwę biblioteki.
![Page 15: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/15.jpg)
Tworzenie bibliotek (pod Linuxem)Program korzystający z biblioteki współdzielonej.
Najpierw kompilujemy pliki źródłowe z opcją -fpic do plików obiektowych:$ g++ -fpic –c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp
Następnie łączymy pliki obiektowe do jednego pliku bibliotecznego libsrc.so:$ g++ –fpic -shared -o libsrc.so src1.o src2.o src3.o
Na koniec należy skompilować plik z programem i wlinkować do niego informacje o bibliotece:$ g++ -Wall -ansi -pedantic prog.cpp$ g++ -o calculation prog.o –L. –lsrc
Przed uruchomieniem programu trzeba zapisać w zmiennej środowiskowej LD_LIBRARY_PATH ścieżkę do biblioteki:$ export LD_LIBRARY_PATH="LD_LIBRARY_PATH:ścieżka"
Teraz można uruchomić skompilowany program:$ ./calculation
![Page 16: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/16.jpg)
Tworzenie bibliotek (pod Linuxem)Program korzystający z biblioteki dynamicznej.
Bibliotekę dynamiczną przygotowujemy tak samo jak bibliotekę współdzieloną libsrc.so:$ g++ -fpic –c -Wall -ansi -pedantic src1.cpp src2.cpp src3.cpp $ g++ –fpic -shared -o libsrc.so src1.o src2.o src3.o
Na koniec należy skompilować plik z programem i dołączyć do niego dynamicznego linkera opcją -ldl:$ g++ -Wall -ansi -pedantic prog.cpp$ g++ -o calculation prog.o –ldl
Teraz można uruchomić skompilowany program:$ ./calculation
Wyjaśnienie: aby skorzystać z dynamicznego linkera należy do programu włączyć
plik nagłówkowy <dlfcn.h>; aby załadować dynamiczną bibliotekę trzeba skorzystać z funkcji
dlopen, dlsym, dlerror i dlclose.
![Page 17: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/17.jpg)
Nazwy zewnętrzne Nazwa jest łączona zewnętrznie jeśli można
jej używać w jednostkach translacji innej niż ta, w której ją zdefiniowano.
Nazwę zewnętrzną deklaruje się za pomocą słowa extern.
Funkcja wbudowana musi być zdefiniowana w każdej jednostce translacji za pomocą identycznej definicji; ta sama reuła odnosi się do funkcji i klas szablonowych.
![Page 18: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/18.jpg)
Nowości z C++11 – szablony zewnętrzne i aliasy szablonów C++ musi stworzyć instancję szablonu zawsze kiedy
napotka w pełni określony szablon w jednostce translacyjnej. W starszym C++ nie jest bowiem możliwe wstrzymanie tworzenia instancji szablonu w takiej sytuacji.
C++11 wprowadza ideę szablonów zewnętrznych w celu zablokowania tworzenia instancji w jednostce translacyjnej. Przykład:extern template class std::vector<MojaKlasa>;
W C++11 można używać aliasów dla szablonów. Przykład:template <typename T> using Vec = std::vector<T,MyAlloc<T>>;
![Page 19: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/19.jpg)
STL STL (ang. Standard Template Library) to
standardowa biblioteka wzorców w C++. Wszystkie składniki STL są wzorcami. STL jest rdzeniem biblioteki standardowej C++. Wszystkie identyfikatory w bibliotece standardowej
C++ zdefiniowane są w przestrzeni nazw std. Zaleta STL – mnóstwo gotowych szablonów klas
pozwalających programować na wyższym poziomie abstrakcji.
Wada STL – brak oczywistości (koniecznie czytaj dokumentację)
![Page 20: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/20.jpg)
STL Biblioteka STL składa się z kilku modułów:
strumienie we/wy, łańcuchy i wyrażenia regularne, kontenery i iteratory, algorytmy i obiekty funkcyjne, wielowątkowość i przetwarzanie współbieżne, internacjonalizacja, klasy narzędziowe.
![Page 21: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/21.jpg)
Pary Szablon struktury pair<> (zdefiniowany w <utility>) umożliwia
potraktowanie dwóch wartości jako pojedynczego elementu. Para posiada dwa pola: first i second. Para posiada konstruktor dwuargumentowy oraz domyślny i kopiujący. Pary można porównywać (operatory == i <). Istnieje szablon funkcji make_pair() do tworzenia pary (typy danych
są rozpoznawane przez kompilator po typach argumentów). Przykłady:
void f (std::pair<int, const char *>);void g (std::pair<const int, std::string>);…std::pair<int, const char *> p(44,”witaj”);f(p); // wywołuje domyślny konstruktor kopiującyg(p); // wywołuje konstruktor wzorcowyg(std::make_pair(44,”witaj”)); // przekazuje dwie // wartości jako parę z wykorzystaniem konwersji // typów
Pary są wykorzystywane w kontenerach map i multimap.
![Page 22: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/22.jpg)
Tuple W C++11 zdefiniowano tuple do przechowywania wielu wartości a nie
tylko dwóch (szablon tuple<> jest analogią do szblony pary pair<>). Tupla posiada wiele ponumerowanych pól, do których dostęp mamy za
pomocą metody get<i>. Tupla posiada konstruktor wieloargumentowy oraz domyślny i
kopiujący. Tuple można porównywać za pomocą operatorów porównań
(porównywanie leksykograficzne). Istnieje szablon funkcji make_tuple() do tworzenia tupli (typy danych
są rozpoznawane przez kompilator po typach argumentów). Istnieje szablon funkcji tie() do tworzenia tupli z referencjami (jako
argumenty podaje się zmienne). Szablon tuple_size<tupletype>::value służy do podania liczby
elementów w tupli. Szablon tuple_element<idx,tupletype>::type służy do
podania typu elementu o indeksie idx w tupli.
![Page 23: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/23.jpg)
Sprytne wskaźniki Sprytne wskaźniki są zdefiniowane w pliku
nagłówkowym <memory>. Zastąpienie szablonu auto_ptr<>. Szablon klasy shared_pointer<> – wiele takich
sprytnych wskaźników może przechowywać wskaźnik do tego samego obiektu, tak że obiekt ten oraz związane z nim zasoby zostaną zwolnione dopiero po likwidacji ostatniego sprytnego wskaźnika.
Szablon klasy unique_pointer<> – tylko jeden sprytny wskaźnik może przechowywać wskaźnik do tego danego obiektu.
![Page 24: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/24.jpg)
Ograniczenia liczbowe Typy numeryczne posiadają ograniczenia zależne od platformy i
są zdefiniowane w szablonie numeric_limits<> (zdefiniowany w <limits>, stałe preprocesora są nadal dostępne w <climits> i <cfloat>).
Wybrane składowe statyczne szablonu numeric_limits<>: is_signed, is_integer, is_exact, is_bounded, is_modulo, has_infinity, has_quiet_NaN, min(), max(), epsilon().
Przykłady:numeric_limits<char>::is_signed;numeric_limits<short>::is_modulo;numeric_limits<long>::max();numeric_limits<float>::min();numeric_limits<double>::epsilon();
![Page 25: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/25.jpg)
Minimum i maksimum Obliczanie wartości minimalnej oraz maksymalnej:
template <class T>inline const T& min (const T &a, const T &b) { return b<a ? b : a; }template <class T>inline const T& max (const T &a, const T &b) { return a<b ? b : a; }
Istnieją też wersje tych szablonów z komparatorami (funkcja lub obiekt funkcyjny):template <class T, class C>inline const T& min (const T &a, const T &b, C comp) { return comp(b,a) ? b : a; }template <class T>inline const T& max (const T &a, const T &b, C comp) { return comp(a,b) ? b : a; }
![Page 26: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/26.jpg)
Minimum i maksimum Przykład 1:
bool int_ptr_less (int *p, int *q) { return *p<*q; }…int x = 33, y = 44;int *px = &x, *py = &y;int *pmax = std::max(px,py,int_ptr_less);
Przykład 2:int i;long l;…l = max(i,l); // BŁĄD // niezgodne typy argumentówl = std::max<long>(i,l); // OK
![Page 27: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/27.jpg)
Zamiana wartości Zamiana dwóch wartości:
template <class T>inline void swap (T &a, T &b) { T tmp(a); a = b; b = tmp; }
Przykład:int x = 33, y = 44;…std::swap(x,y);
![Page 28: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/28.jpg)
Operatory porównywania Cztery funkcje szablonowe (zdefiniowane w <utility>) na podstawie
operatorów == i < definiują operatory porównań !=, <=, >= i >. Funkcje te są umieszczone w przestrzeni nazw std::rel_ops. Przykład:
class X { …public: bool operator== (const X &x) const throw(); bool operator< (const X &x) const throw(); …};…void foo () { using namespace std::rel_ops; X x1, x2; … if (x1!=x2) { … } …}
![Page 29: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/29.jpg)
Kontenery Kontenery służą do przechowywania i
zarządzania kolekcjami danych. Rodzaje kontenerów:
Kontenery sekwencyjne, gdzie każdy element ma określoną pozycję. Na przykład: vector, deque, list.
Kontenery uporządkowane (w tym asocjacyjne), gdzie pozycja elementu zależy od jego wartości. Na przykład: set, multiset, map, multimap.
![Page 30: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/30.jpg)
Elementy kontenerów Elementy kontenerów muszą spełniać wymagania
podstawowe: element musi być kopiowalny (konstruktor kopiujący), element musi być przypisywalny (przypisanie kopiujące), element musi być zniszczalny (publiczny destruktor).
W pewnych sytuacjach elementy kontenerów muszą spełniać wymagania dodatkowe: konstruktor domyślny (utworzenie niepustego kontenera), operator porównywania == (wyszukiwanie), operator porównywania < (kryterium sortowania).
![Page 31: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/31.jpg)
Semantyka wartości a semantyka referencji Kontenery STL realizują semantykę wartości:
tworzą wewnętrzne kopie swoich elementów oraz zwracają kopie tych elementów.
Semantykę referencji można zaimplementować samodzielnie za pomocą inteligentnych wskaźników – wskaźniki te mają umożliwiać zliczanie referencji dla obiektów, do których odnoszą się wskaźniki.
![Page 32: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/32.jpg)
Kontenery sekwencyjne– wektory Wektor vector<> (zdefiniowany w <vector>) przechowuje
swoje elementy w tablicy dynamicznej. Uzyskujemy szybki dostęp do każdego elementu za pomocą
indeksowania. Dołączanie i usuwanie elementów na końcu wektora jest bardzo
szybkie, ale wstawienie lub usunięcie elementu ze środka zabiera więcej czasu.
Przykład:vector<int> coll;…for (int i=1; i<=6; ++i) coll.push_back(i);…for (int i=0; i<coll.size(); ++i) cout << coll[i] << ’ ’;cout << endl;
![Page 33: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/33.jpg)
Kontenery sekwencyjne– kolejki o dwóch końcach Kolejka o dwóch końcach deque<> (zdefiniowana w <deque>)
przechowuje swoje elementy w tablicy dynamicznej, która może rosnąć w dwie strony.
Uzyskujemy szybki dostęp do każdego elementu za pomocą indeksowania.
Dołączanie i usuwanie elementów na końcu i na początku kolejki jest bardzo szybkie, ale wstawienie lub usunięcie elementu ze środka zabiera więcej czasu.
Przykład:deque<float> coll;…for (int i=1; i<=6; ++i) coll.push_front(i*1.234);…for (int i=0; i<coll.size(); ++i) cout << coll[i] << ’ ’;cout << endl;
![Page 34: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/34.jpg)
Kontenery sekwencyjne– listy Lista list<> (zdefiniowana w <list>) przechowuje swoje
elementy w liście dwukierunkowej. W listach nie ma swobodnego dostępu do elementów kolekcji. Dołączanie i usuwanie elementów na końcu i na początku listy
jest bardzo szybkie, ale dostanie się do elementu ze środka zabiera dużo czasu.
Przykład:list<char> coll;…for (char c=’a’; c<=’z’; ++c) coll.push_back(c);…while (!coll.empty()) { cout << coll.front() << ’ ’; coll.pop_front(); }cout << endl;
![Page 35: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/35.jpg)
Kontenery sekwencyjne– łańcuchy i tablice Obiektów klas łańcuchowych, czyli basic_string<>, string i wstring, można używać jak kontenerów sekwencyjnych. Są one podobne w zachowaniu do wektorów.
Innym rodzajem kontenera może być tablica. Nie jest to klasa i nie ma żadnych metod ale konstrukcja STL umożliwia uruchamianie na tablicach różnych algorytmów (tak jak na kontenerach).
![Page 36: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/36.jpg)
Kontenery uporządkowane Kontenery uporządkowane wykonują automatycznie sortowanie
swoich elementów. Asocjacyjne kontenery uporządkowane przechowują pary klucz-
wartość (odpowiednio first i second) i sortowanie następuje po kluczach.
Domyślnie elementy lub klucze są porządkowane przy pomocy operatora <.
Kontenery uporządkowane są implementowane w postaci zrównoważonych drzew BST (drzewa czerwono-czarne).
Wszystkie kontenery uporządkowane posiadają domyślny parametr wzorca służący sortowaniu (domyślnym jest operator <).
Rodzaje kontenerów: zbiory set<>, wielozbiory multiset<>, mapy map<> i multimapy multimap<>.
![Page 37: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/37.jpg)
Adaptatory kontenerów Adaptatory kontenerów to kontenery
wykorzystujące ogólną strukturę innych kontenerów do realizacji pewnych specyficznych potrzeb.
Adaptatorami kontenerów są stosy stack<>, kolejki queue<> i kolejki priorytetowe priority_queue<>.
![Page 38: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/38.jpg)
Iteratory Iterator to specjalny obiekt, który potrafi iterować po elementach
kolekcji. Iterator ma zaimplementowaną semantykę wskaźnika – posiada
operator wyłuskania elementu *, operatory przechodzenia do elementówsąsiednich ++ i -- oraz operatory porównywania pozycji == i !=.
Wszystkie kontenery udostępniają funkcje tworzące iteratory do nawigowania po ich elementach – funkcja begin() zwraca iterator wskazujący na pozycję z pierwszym elementem w kolekcji a funkcja end() zwraca iterator wskazujący pozycję za ostatnim elementem.
Każdy kontener definiuje dwa typy iteratorów – kontener::iterator przeznaczony do iterowania po elementach z możliwością odczytu i zapisu oraz kontener::const_iterator przeznaczony do iterowania po elementach tylko z możliwością odczytu.
![Page 39: C++ wykład 11 (30.05.2013)](https://reader034.vdocuments.pub/reader034/viewer/2022052512/56814bec550346895db8ca39/html5/thumbnails/39.jpg)
Iteratory Przykład 1:
list<char> coll;…list<char>::const_iterator pos;for (pos=coll.begin(); pos!=coll.end(); ++pos) cout << *pos << ’ ’;cout << endl;
Przykład 2:list<char> coll;…list<char>::iterator pos;for (pos=coll.begin(); pos!=coll.end(); ++pos) *pos = toupper(*pos);