Upload
vuonghanh
View
224
Download
0
Embed Size (px)
Citation preview
Książki o STLKsiążki o STL Nicolai M. Josuttis: C++ Biblioteka standardowa Nicolai M. Josuttis: C++ Biblioteka standardowa
Podręcznik Programisty, Helion 2003, Podręcznik Programisty, Helion 2003, przykłady: przykłady: ftp://ftp.helion.pl/przyklady/cpbspp.zipftp://ftp.helion.pl/przyklady/cpbspp.zip
Grębosz J.: Pasja C++, RM, W-waGrębosz J.: Pasja C++, RM, W-wa Inne (wymienione na wykładzie Nr 1)Inne (wymienione na wykładzie Nr 1)
Biblioteka standardowa języka C++Biblioteka standardowa języka C++
STLSTL
Klasy strumienioweKlasy strumieniowe Klasy łańcuchoweKlasy łańcuchowe
(biblioteka zdefiniowana w namespace std )(biblioteka zdefiniowana w namespace std )
Biblioteka standardowa języka C++Biblioteka standardowa języka C++ Główne składnikiGłówne składniki
KonteneryKontenery (listy, wektory, etc.) (listy, wektory, etc.) IteratoryIteratory (interfejs pomiędzy algorytmami a kontenerami) (interfejs pomiędzy algorytmami a kontenerami) AlgorytmyAlgorytmy (proste, nie bardziej skomplikowane od wyszukiwania i (proste, nie bardziej skomplikowane od wyszukiwania i
sortowanie)sortowanie) Inne (obiekty funkcyjne, adaptory, szablony pomocnicze...)Inne (obiekty funkcyjne, adaptory, szablony pomocnicze...)
STL to biblioteka STL to biblioteka wzorcówwzorców!! Dane odseparowane od metod (a co z ideą OOP?)Dane odseparowane od metod (a co z ideą OOP?) Zaprojektowane dla programowania wysokopoziomowegoZaprojektowane dla programowania wysokopoziomowego Zaprojektowane dla programowania wydajnegoZaprojektowane dla programowania wydajnego
BTW: rząd złożoności algorytmuBTW: rząd złożoności algorytmu
O-notacjaO-notacja
Wyszukiwanie w posortowanej tablicy:Wyszukiwanie w posortowanej tablicy: O(logO(log22((nn)))) Wyszukiwanie w nieuporządkowanej tablicy: Wyszukiwanie w nieuporządkowanej tablicy: O(O(nn)) Quicksort:Quicksort: O(O(nn ·· log log22((nn)))) Sortowanie bąbelkowe:Sortowanie bąbelkowe: O(O(nn22))
KonteneryKontenery SekwencyjneSekwencyjne
vector (tablica dynamiczna)vector (tablica dynamiczna) dequeue (tablica dynamiczna dwukierunkowa)dequeue (tablica dynamiczna dwukierunkowa) list (lista dwukierunkowa)list (lista dwukierunkowa)
array (C++11) – tablica o stałym rozmiarzearray (C++11) – tablica o stałym rozmiarze forward_list (C++11) – lista jednokierunkowaforward_list (C++11) – lista jednokierunkowa
tablica i string --- nie są kontenerami STL, ale można je tablica i string --- nie są kontenerami STL, ale można je przetwarzać za pomocą algorytmów STLprzetwarzać za pomocą algorytmów STL
adaptery kontenerówadaptery kontenerów stack (kolejka LIFO), queue (kolejka FIFO), priority_queuestack (kolejka LIFO), queue (kolejka FIFO), priority_queue
Kontenery asocjacyjneKontenery asocjacyjne Asocjacyjne Asocjacyjne
set (drzewo binarne)set (drzewo binarne) multisetmultiset map, multimapmap, multimap
Asocjacyjne nieuporządkowane (C++11)Asocjacyjne nieuporządkowane (C++11)(zaimplementowane za pomoca tablicy mieszającej zamiast drzewa binarnego, (zaimplementowane za pomoca tablicy mieszającej zamiast drzewa binarnego,
w starszych implementacjach znane jako hash_*)w starszych implementacjach znane jako hash_*) unordered_set, unordered_multiset, unordered_set, unordered_multiset, unordered_map, unordered_multimapunordered_map, unordered_multimap
KonteneryKontenery vector vector
Zaimplementowany jako tablica dynamicznaZaimplementowany jako tablica dynamiczna
szybkie push_back()szybkie push_back() szybki operator[]szybki operator[]
wolne insert()wolne insert()
KonteneryKontenery deque deque
Zaimplementowany jako tablica dynamicznaZaimplementowany jako tablica dynamiczna
szybkie push_back() szybkie push_back() (vector może być szybszy)(vector może być szybszy) szybkie push_front() szybkie push_front() (nieobsługiwany przez vector)(nieobsługiwany przez vector) szybki operator[]szybki operator[]
wolny insert()wolny insert()
KonteneryKontenery list list
Zaimplementowana jako lista Zaimplementowana jako lista dwukierunkowadwukierunkowa
szybkie push_back()szybkie push_back() szybkie push_front()szybkie push_front() szybkie insert()szybkie insert()
Nie ma operatora operator[]Nie ma operatora operator[]
przykład: list1.cppprzykład: list1.cpp
IteratoryIteratory Iteratory zachowują się jak zwyczajne wskaźniki ...Iteratory zachowują się jak zwyczajne wskaźniki ...
* * ->-> ++++ ---- ==== !=!= == (vector, deq: -, <, >, +(int) )(vector, deq: -, <, >, +(int) )
Ale działają dla wszystkich kontenerów!Ale działają dla wszystkich kontenerów! container.begin()container.begin() // zwróć iterator do pierwszego elementu.// zwróć iterator do pierwszego elementu. container.end()container.end() // ... do ostatniego// ... do ostatniego
przykład: list2.cppprzykład: list2.cpp
Kontenery asocjacyjneKontenery asocjacyjne set set
Zaimplementowany jako drzewo binarneZaimplementowany jako drzewo binarne Sowrtowanie przy wstawianiu (porównywanie domyślnym Sowrtowanie przy wstawianiu (porównywanie domyślnym
operatorem<() )operatorem<() ) Odpowiednik zbiorów matematycznychOdpowiednik zbiorów matematycznych
metoda find()metoda find()
szybkie insert()szybkie insert()
nie ma: push_back()nie ma: push_back() nie ma: push_front()nie ma: push_front() nie ma: operatora []nie ma: operatora []
Kontenery asocjacyjneKontenery asocjacyjne multiset multiset
Dozwolone powtórzenia tej samej wartościDozwolone powtórzenia tej samej wartości Uporządkowanie wewnątrz grupy elementów o Uporządkowanie wewnątrz grupy elementów o
tych samych wartościach jest niezdefiniowanetych samych wartościach jest niezdefiniowane
Kontenery asocjacyjneKontenery asocjacyjne multimapmultimap
multiset dla par: klucz, wartość – użyj make_pair() multiset dla par: klucz, wartość – użyj make_pair()
Kontenery asocjacyjneKontenery asocjacyjne mapmap
set dla par: klucz, wartość – użyj make_pair()set dla par: klucz, wartość – użyj make_pair()
Tylko dla kontenera mapTylko dla kontenera map: operator[key](): operator[key]() Indeksowanie wartością (tablica asocjacyjna) Indeksowanie wartością (tablica asocjacyjna)
Adaptery kontenerówAdaptery kontenerów stack (kolejka LIFO)stack (kolejka LIFO) queue (kolejka FIFO)queue (kolejka FIFO) priority_queue (kolejka priorytetowa)priority_queue (kolejka priorytetowa)
stackstack header <stack>header <stack> prosta koleja LIFO zaimplementowana za pomocą dequeprosta koleja LIFO zaimplementowana za pomocą deque
może być oparta o kontener mający: back(), push_back(), pop_back()może być oparta o kontener mający: back(), push_back(), pop_back() wystarczy podać 2gi argument szablonu, np.: stack<int, vector<int>>wystarczy podać 2gi argument szablonu, np.: stack<int, vector<int>>
po prostu przekierowuje swoje metody do deque aby uzyskać kolejkę LIFOpo prostu przekierowuje swoje metody do deque aby uzyskać kolejkę LIFO example: cont/stack1.cppexample: cont/stack1.cpp
push()push() pop()pop() top() top() // pobierz wartość elementu ze szczytu stosu// pobierz wartość elementu ze szczytu stosu
// ale nie usuwaj go// ale nie usuwaj go size()size() // zwróć rozmiar stosu // zwróć rozmiar stosu empty()empty() // czy stos jest pusty? // czy stos jest pusty? operatory : ==, !=, <, >, <=, >= operatory : ==, !=, <, >, <=, >= // == zwraca 1 gdyrozmiary i elementy // == zwraca 1 gdyrozmiary i elementy
identyczneidentyczne bez innych metod lub operatorówbez innych metod lub operatorów
queue queue header <queue>header <queue> prosta kolejka FIFO zaimplementowana za pomocą dequeprosta kolejka FIFO zaimplementowana za pomocą deque
może być oparta o kontener mający : front(), back(), push_back(), pop_front()może być oparta o kontener mający : front(), back(), push_back(), pop_front() wystarczy podać 2gi argument szablonu, np.: queue<int, list<int>>wystarczy podać 2gi argument szablonu, np.: queue<int, list<int>>
po prostu przekierowuje swoje metody do deque aby uzyskać kolejkę FIFOpo prostu przekierowuje swoje metody do deque aby uzyskać kolejkę FIFO przykład: cont/queue1.cppprzykład: cont/queue1.cpp
push()push() pop()pop() back() back() // zwróć wartość ostatnio wstawionego elementu// zwróć wartość ostatnio wstawionego elementu
// ale go nie usuwaj// ale go nie usuwaj front() front() // zwróć wartość elementu z przodu kolejni// zwróć wartość elementu z przodu kolejni
// ale go nie usuwaj// ale go nie usuwaj size()size() // zwróć rozmiar stosu // zwróć rozmiar stosu empty()empty() // czy stos jest pusty? // czy stos jest pusty? operatory: ==, !=, <, >, <=, >=operatory: ==, !=, <, >, <=, >= // == zwraca 1 rozmiary i elementy // == zwraca 1 rozmiary i elementy
identyczneidentyczne bez innych metod lub operatorówbez innych metod lub operatorów
priority_queue priority_queue header <queue>header <queue> prosta kolejka priorytetowa zaimplementowana za pomocą vectorprosta kolejka priorytetowa zaimplementowana za pomocą vector
może być oparta o kontener mający: front(), push_back(), pop_front(), operator[]może być oparta o kontener mający: front(), push_back(), pop_front(), operator[] wystarczy podać 2gi argument szablonu, np.: priority_queue<int, deque<int>>wystarczy podać 2gi argument szablonu, np.: priority_queue<int, deque<int>> 3ci argument to kryterium sortowania (domyślnie: operator< )3ci argument to kryterium sortowania (domyślnie: operator< )
priority_queue<int, vector<int>, greater<int>>priority_queue<int, vector<int>, greater<int>> przekierowuje swoje metody do metod kontenera vectorprzekierowuje swoje metody do metod kontenera vector przykład: cont/pqueue1.cppprzykład: cont/pqueue1.cpp
push()push() pop()pop() top() top() // zwróć wartość elementu o największym priorytecie// zwróć wartość elementu o największym priorytecie
// ale go nie usuwaj z kolejki// ale go nie usuwaj z kolejki size()size() // liczba elementów// liczba elementów empty()empty() // czy kolejka pusta // czy kolejka pusta bez innych metod lub operatorów (w tym operatora ==, etc.)bez innych metod lub operatorów (w tym operatora ==, etc.)
Algorytmy STLAlgorytmy STL Operują na kontenerach za pomocą iteratorówOperują na kontenerach za pomocą iteratorów
Sposób uniwersalny, ale nie tak szybki jak metody kontenerówSposób uniwersalny, ale nie tak szybki jak metody kontenerów Dla niektórych kombinacji algorytm/kontener wolneDla niektórych kombinacji algorytm/kontener wolne Możliwe jednoczesne działanie na kontenerach różnych typówMożliwe jednoczesne działanie na kontenerach różnych typów
Tylko podstawowe, proste algorytmyTylko podstawowe, proste algorytmy Parametryzowalne przez rozmaite iteratoryParametryzowalne przez rozmaite iteratory Parametryzowalne przez obiekty funkcyjne i adaptoryParametryzowalne przez obiekty funkcyjne i adaptory
Bardziej podatne na błędy programisty od metod kontenerówBardziej podatne na błędy programisty od metod kontenerów
Algorytmy STLAlgorytmy STL Przykład: algo1.cppPrzykład: algo1.cpp
min_elementmin_element // operator<()// operator<() max_elementmax_element // operator<()// operator<() sortsort // operator<()// operator<() findfind // operator==()// operator==() reversereverse // operator=()// operator=()
min_element (coll.begin(), coll.end())min_element (coll.begin(), coll.end()) Zakres to Zakres to [[ coll.begin(), coll.end() coll.begin(), coll.end() )) ((przykład: find1.cppprzykład: find1.cpp)) Właściwa definicja zakresu to zadanie programistyWłaściwa definicja zakresu to zadanie programisty Koniec zakresu powinien być osiągany przez ++’owanie początkuKoniec zakresu powinien być osiągany przez ++’owanie początku Co gdy nie mamy pewności co jest końcem a co początkiem?Co gdy nie mamy pewności co jest końcem a co początkiem?
DygresjaDygresja// bez algorytmu, pre - C++11// bez algorytmu, pre - C++11list<char>::const_iterator pos;list<char>::const_iterator pos;for (pos = coll.begin(); pos != coll.end(); ++pos)for (pos = coll.begin(); pos != coll.end(); ++pos)
cout << *pos << ' ';cout << *pos << ' ';
// nadal bez algorytmu, C++11: auto i for zakresowe// nadal bez algorytmu, C++11: auto i for zakresowefor (const auto & car : coll)for (const auto & car : coll)
cout << car << ' ';cout << car << ' ';
// algorytm i funkcja lambda - rozwiązanie preferowane// algorytm i funkcja lambda - rozwiązanie preferowanefor_each(coll.begin(), coll.end(), for_each(coll.begin(), coll.end(),
[](const auto & car) { cout << car << ' '; });[](const auto & car) { cout << car << ' '; });
Algorytmy STLAlgorytmy STL copy (coll1.begin(), coll1.end(), coll2.begin()); copy (coll1.begin(), coll1.end(), coll2.begin());
Koniec zakresu podany tylko dla pierwszego zakresuKoniec zakresu podany tylko dla pierwszego zakresu Rozmiar zakresu docelowego Rozmiar zakresu docelowego musimusi być wystarczający być wystarczający
Algorytm przeprowadza wyłącznie proste nadpisywanieAlgorytm przeprowadza wyłącznie proste nadpisywanie … … bez sprawdzania rozmiaru zakresu docelowegobez sprawdzania rozmiaru zakresu docelowego
(iteratory to interfejs do elementów kontenera, nie do kontenera)(iteratory to interfejs do elementów kontenera, nie do kontenera) Właściwy rozmiar kolekcji to odpowiedzialność/zadanie Właściwy rozmiar kolekcji to odpowiedzialność/zadanie
programisty programisty ((przykład: copy2.cppprzykład: copy2.cpp)) Dla niektórych kontenerów (sekwencyjne) ustawienie rozmiaru Dla niektórych kontenerów (sekwencyjne) ustawienie rozmiaru
początkowego jest prostepoczątkowego jest proste
Iteratory STLIteratory STL Wielkość zakresu musi być wystarczająca, albo ...Wielkość zakresu musi być wystarczająca, albo ... copy (coll1.begin(), coll1.end(),copy (coll1.begin(), coll1.end(),
inserter(inserter(coll2coll2, coll2.begin(), coll2.begin())) ); );
... albo użyj iteratorów wstawiających (inserter) ;) ... albo użyj iteratorów wstawiających (inserter) ;) ((copy3.cppcopy3.cpp)) inserter dla wszystkich kontenerów, które mają metodę insert()inserter dla wszystkich kontenerów, które mają metodę insert()
Wstawia przed podaną lokalizacjąWstawia przed podaną lokalizacją Dla kontenerów asocjacyjnych lokalizacja jest tylko wskazówkąDla kontenerów asocjacyjnych lokalizacja jest tylko wskazówką
back_inserter dla kontenerów, które mają metodę push_back()back_inserter dla kontenerów, które mają metodę push_back() front_inserter dla kontenerów, które mają metodę push_front()front_inserter dla kontenerów, które mają metodę push_front()
Iteratory STLIteratory STL Iteratory strumienioweIteratory strumieniowe
Zachowują się jak zwyczajne iteratoryZachowują się jak zwyczajne iteratory Mają interfejs zwykłych iteratorówMają interfejs zwykłych iteratorów
Operują na strumieniach i/o Operują na strumieniach i/o (ioiter1.cpp)(ioiter1.cpp) istream_iterator<string>(cin) istream_iterator<string>(cin)
++iter dla stream>>temp, *iter aby pobrać temp++iter dla stream>>temp, *iter aby pobrać temp istream_iterator<string>()istream_iterator<string>()
Iterator końca srtumienia (zakresu strumienia)Iterator końca srtumienia (zakresu strumienia)
Iteratory STLIteratory STL Iteratory odwrotne (reverse iterator)Iteratory odwrotne (reverse iterator)
Mają interfejs zwykłych iteratorówMają interfejs zwykłych iteratorów Zachowują się odwrotnie Zachowują się odwrotnie (rter1.cpp)(rter1.cpp)
container.rbegin() wskazuje na ostatni element container.rbegin() wskazuje na ostatni element (nie pozycję (nie pozycję popo ostatnim) ostatnim)
container.rend() wskazuje na pozycję przed pierwszym!container.rend() wskazuje na pozycję przed pierwszym! ++ to --, -- to ++, itd. ++ to --, -- to ++, itd.
Algorytmy STLAlgorytmy STL Usuwanie elementów z kontenera Usuwanie elementów z kontenera
Algorytm remove(...)Algorytm remove(...) Tak naprawdę nie usuwa zawartości kontenera Tak naprawdę nie usuwa zawartości kontenera ((remove1.cppremove1.cpp)) Nie ma dostępu do kontenera, a tylko do elementówNie ma dostępu do kontenera, a tylko do elementów Nie działa dla kontenerów asocjacyjnychNie działa dla kontenerów asocjacyjnych Zwraca nowy koniec zakresu (element następny po ostatnim)Zwraca nowy koniec zakresu (element następny po ostatnim)
Użyj metody kontener.erase(...) by się pozbyć elementów Użyj metody kontener.erase(...) by się pozbyć elementów ((remove2.cppremove2.cpp))
Wiele wersjiWiele wersji Działa dla kontenerów asocjacyjnych Działa dla kontenerów asocjacyjnych ((remove3.cppremove3.cpp))
Funkcja jako argument algorytmuFunkcja jako argument algorytmu
Funkcje jednoargumentowe Funkcje jednoargumentowe przykłady: foreach1.cpp, transform1.cppprzykłady: foreach1.cpp, transform1.cpp
Predykaty Predykaty Jeden argument i wynik bool Jeden argument i wynik bool
((przykład: prime1.cppprzykład: prime1.cpp)) Dwa argumenty i wynik bool Dwa argumenty i wynik bool
((przykład: sort1.cppprzykład: sort1.cpp))
Obiekt funkcyjny jako argument Obiekt funkcyjny jako argument algorytmualgorytmu
Obiekty funkcyjneObiekty funkcyjne Zachowują się jak funkcje, ale wykorzystują Zachowują się jak funkcje, ale wykorzystują
operator()() operator()() foreach2.cppforeach2.cpp
Są obiektamiSą obiektami Lepiej optymalizowane przez kompilator Lepiej optymalizowane przez kompilator Mogą posiadać zmienne klasowe, „wewnętrzny stan” Mogą posiadać zmienne klasowe, „wewnętrzny stan”
przekazany jako argument konstruktora przekazany jako argument konstruktora ((add1.cppadd1.cpp)) Można mieć wiele obiektów funkcyjnych tej samej Można mieć wiele obiektów funkcyjnych tej samej
klasyklasy
Obiekt funkcyjny jako argument Obiekt funkcyjny jako argument algorytmualgorytmu
Predefiniowane szablony obiektów funkcyjnychPredefiniowane szablony obiektów funkcyjnych less<>, greater <>less<>, greater <>
set<int> s;set<int> s; domyślnie oznacza domyślnie oznacza set<int, less<int> > s;set<int, less<int> > s;
można również:można również: set<int, greater<int> > s;set<int, greater<int> > s;
negate<>, multiply<> negate<>, multiply<> // do użycia w algorytmie transform(...)// do użycia w algorytmie transform(...)
Adaptory funkcjiAdaptory funkcji Definiują przypadki szczególne użycia funkcjiDefiniują przypadki szczególne użycia funkcji Modyfikują funkcję, gdy wymagany jest inny Modyfikują funkcję, gdy wymagany jest inny
interfejs (tj. lista argumentów)interfejs (tj. lista argumentów) bind2nd(less<int>(),50)bind2nd(less<int>(),50) ((fo1.cppfo1.cpp))
Tworzymy domyślny drugi argumentTworzymy domyślny drugi argument
Funkcje lambda (a.k.a. wyrażenia Funkcje lambda (a.k.a. wyrażenia lambda, „lambdy”)lambda, „lambdy”)
Lokalna, nienazwana funkcja, do użycia jako argument funkcji, szablonu (np. Algorytmów STL) Lokalna, nienazwana funkcja, do użycia jako argument funkcji, szablonu (np. Algorytmów STL) zamiast zwykłej funkcji lub obiektu funkcyjnegozamiast zwykłej funkcji lub obiektu funkcyjnego
[&](int a, int b) { return[&](int a, int b) { return v[a].name<v[b].name; }v[a].name<v[b].name; } Typ funkcji jest wnioskowany z wyrażenia return, można podać używając alternatywnej składni Typ funkcji jest wnioskowany z wyrażenia return, można podać używając alternatywnej składni
deklaracjideklaracji
[] – capture list, informuje jakie zmienne z lokalnego zakresu są widoczne w ciele funkcji lambda, [] – capture list, informuje jakie zmienne z lokalnego zakresu są widoczne w ciele funkcji lambda, [] [] – nie widać nic (z zakresu, ale widać argumenty)– nie widać nic (z zakresu, ale widać argumenty)[&] [&] – wszystko, jako referencje– wszystko, jako referencje[=] [=] – wszystko czego używa funkcja, przekazane przez zmienną– wszystko czego używa funkcja, przekazane przez zmienną
jako stała ( aby przy przekazywaniu przez zmienną móc ją jako stała ( aby przy przekazywaniu przez zmienną móc ją modyfikować należy użyć „mutable” po nawiasie modyfikować należy użyć „mutable” po nawiasie zamykającym listę argumentów f. lambda) zamykającym listę argumentów f. lambda)
[a, &c][a, &c] – zmienna a przez wartość, zmienna c jako referencja– zmienna a przez wartość, zmienna c jako referencja
Użyj funkcji lambda, jeżeli chcesz wykonać zadanie proste i typowe, do innych zadań lepsze Użyj funkcji lambda, jeżeli chcesz wykonać zadanie proste i typowe, do innych zadań lepsze funkcje i obiekty funkcyjnefunkcje i obiekty funkcyjne
Funkcje lambdaFunkcje lambda
void f(vector<Record>& v)void f(vector<Record>& v){{
vector<int> indices(v.size());vector<int> indices(v.size());int count = 0;int count = 0;generate(indices.begin(),indices.end(),generate(indices.begin(),indices.end(),
[&count](){ return count[&count](){ return count++++; }; }););
// // posortuj indeksy w kolejności określonej przez pole name rekorduposortuj indeksy w kolejności określonej przez pole name rekordu::std::sort(indices.begin(), indices.end(), std::sort(indices.begin(), indices.end(),
[&](int a, int b) { return v[a].name<v[b].name; }[&](int a, int b) { return v[a].name<v[b].name; }););// ...// ...
}}
Funkcje lambda (od C++14)Funkcje lambda (od C++14)
Argumenty funkcji mogą być typu autoArgumenty funkcji mogą być typu auto
Argumenty w capture list mogą mieć wartości domyślneArgumenty w capture list mogą mieć wartości domyślne
można w ten sposób wymusić przekazanie argumentu przez r-wartość/move można w ten sposób wymusić przekazanie argumentu przez r-wartość/move semanticssemantics
std::unique_ptr<int> ptr(new int(10)); std::unique_ptr<int> ptr(new int(10)); auto lambda = [value = std::move(ptr)] {return *value;}; auto lambda = [value = std::move(ptr)] {return *value;};
można użyć wewnątrz funkcji zmiennych niewidocznych w miejscu można użyć wewnątrz funkcji zmiennych niewidocznych w miejscu wywołania funkcji utworzonych w capture list (typ wyznaczony jak przez wywołania funkcji utworzonych w capture list (typ wyznaczony jak przez auto)auto)
auto lambda = [value = 1] {return value;}; auto lambda = [value = 1] {return value;};
STL, błędy i wyjątkiSTL, błędy i wyjątki Zaprojektowana dla maksymalizacji prędkościZaprojektowana dla maksymalizacji prędkości
W przypadku błędnego użycia (np. *end()=something) zachowanie jest W przypadku błędnego użycia (np. *end()=something) zachowanie jest niezdefiniowane, miejmy nadzieją że błąd ujawni się wcześnieniezdefiniowane, miejmy nadzieją że błąd ujawni się wcześnie
Ostrożnie z iteratorami i zakresamiOstrożnie z iteratorami i zakresami Tylko minimalne sprawdzenia są realizowane (wyjątek bad_alloc)Tylko minimalne sprawdzenia są realizowane (wyjątek bad_alloc)
Jest wersja debug bibliotekiJest wersja debug biblioteki Użyj jej!!!Użyj jej!!!
Niektóre metody niektórych kontenerów są „transaction-safe”Niektóre metody niektórych kontenerów są „transaction-safe” A niektóre nie są!A niektóre nie są! Sprawdź w dokumentacji!Sprawdź w dokumentacji!
Wybrane inne elementy bibliotekiWybrane inne elementy biblioteki Klasa bitsetKlasa bitset
Inteligentne wskaźnikiInteligentne wskaźniki auto_ptr (deprecated)auto_ptr (deprecated) unique_ptrunique_ptr shared_ptrshared_ptr weak_ptrweak_ptr
bitset bitset header header <bitset><bitset> wygodna klasa do przetwarzania pól bitowych o wygodna klasa do przetwarzania pól bitowych o
znanym rozmiarzeznanym rozmiarzebitset<20> flags;bitset<20> flags;
wykonywania bitowego i/owykonywania bitowego i/o example: cont/bitset1.cppexample: cont/bitset1.cpp
i całkowitoliczbowego i/o w formacie binarnymi całkowitoliczbowego i/o w formacie binarnym example: cont/bitset2.cppexample: cont/bitset2.cpp
bez konstruktora kopiującego i op. przypisaniabez konstruktora kopiującego i op. przypisania
bitsetbitset bitset - konstruktorybitset - konstruktory
bitset<bits>::bitset() bitset<bits>::bitset() bitset<bits>::bitset(unsigned long val)bitset<bits>::bitset(unsigned long val)bitset<bits>::bitset(const string &sc)bitset<bits>::bitset(const string &sc)// bez inicjalizacji char*, kilka wariantów inicjalizacji string-iem// bez inicjalizacji char*, kilka wariantów inicjalizacji string-iem
metody i operatory klasy bitsetmetody i operatory klasy bitsetsize() size() // rzwróć rozmiar bitset-u// rzwróć rozmiar bitset-ucount() count() // policz jedynki// policz jedynkiany() any() // 1 jeżeli przynajmniej 1 bit ustawiony// 1 jeżeli przynajmniej 1 bit ustawionynone() none() // !any()// !any()test(size_t idx) test(size_t idx) // czy bit o indeksjie idx jest ustawiony?// czy bit o indeksjie idx jest ustawiony?operator==(const bitset<bits>& arg) operator==(const bitset<bits>& arg) operator!=(const bitset<bits>& arg) operator!=(const bitset<bits>& arg) … …
bitsetbitset metody i operatory klasy bitsetmetody i operatory klasy bitset
set() set() // ustaw wszystkie bity na jedynki// ustaw wszystkie bity na jedynkiset(size_t idx, int value=1) set(size_t idx, int value=1) reset() reset() // wszystkie na 0// wszystkie na 0reset(size_t idx)reset(size_t idx) // bit o indeksie idx na 0// bit o indeksie idx na 0flip() flip() // zaneguj wszystkie bity// zaneguj wszystkie bityflip(size_t idx) flip(size_t idx)
bitowe operatory (rozmiary argumentów muszą pasować): bitowe operatory (rozmiary argumentów muszą pasować): ^= |= &= ^ | & ~^= |= &= ^ | & ~bitowe przesunięcia (bitowe przesunięcia (size_tsize_t argument): argument): <<= << >>= >><<= << >>= >>
operatory łańcuchowe: operatory łańcuchowe: << >><< >>
bool operator[] (size_t idx) const bool operator[] (size_t idx) const // zachowanie niezdefiniowane gdy idx poza zasięgiem// zachowanie niezdefiniowane gdy idx poza zasięgiembitset<bits>::reference operator[] (size_t idx) bitset<bits>::reference operator[] (size_t idx) // zwróć obiekt specjalnego typu (tzw. proxy)// zwróć obiekt specjalnego typu (tzw. proxy)// za pomocą którego następnie można: =(bool), =(const reference &), flip(), operator~(), bool()// za pomocą którego następnie można: =(bool), =(const reference &), flip(), operator~(), bool()
to_ulong(), to_string()to_ulong(), to_string()
Inteligentne wskaźnikiInteligentne wskaźniki auto_ptrauto_ptr
ścisła własność wskazywanej danej, deprecatedścisła własność wskazywanej danej, deprecated
unique_ptrunique_ptr ścisła własność wskazywanej danej, od C++11 zastępuje ścisła własność wskazywanej danej, od C++11 zastępuje auto_ptrauto_ptr
shared_ptrshared_ptr współdzielony wskaźnik ze zliczaniem referencji do wskazywanego obiektuwspółdzielony wskaźnik ze zliczaniem referencji do wskazywanego obiektu
weak_ptrweak_ptr pomocniczy wskaźnik do danych zarządzanych przez pomocniczy wskaźnik do danych zarządzanych przez shared_ptrshared_ptr do przerywania pętli zależności do przerywania pętli zależności shared_ptrshared_ptr
Inteligentne wskaźnikiInteligentne wskaźniki
auto_ptrauto_ptr ścisła własność wskazywanej danejścisła własność wskazywanej danej niezgodny z metodami przenoszącymi C++11niezgodny z metodami przenoszącymi C++11 niezgodny z kontenerami i algorytmami STLniezgodny z kontenerami i algorytmami STL zachowany dla zgodności w dół, deprecatedzachowany dla zgodności w dół, deprecated zamiast niego użyj zamiast niego użyj unique_ptrunique_ptr!!
Inteligentne wskaźnikiInteligentne wskaźniki unique_ptrunique_ptr
ścisła własność wskazywanej danejścisła własność wskazywanej danej zastępuje zastępuje auto_ptrauto_ptr sprzed C++11 sprzed C++11 jego destruktor niszczy wskazywaną danąjego destruktor niszczy wskazywaną daną bez konstruktora kopiującego i operatora przypisaniabez konstruktora kopiującego i operatora przypisania z konstruktorem przenoszącym i operatorem przeniesienia z konstruktorem przenoszącym i operatorem przeniesienia podobnie jak podobnie jak auto_ptrauto_ptr może być użyty do tworzenia źródeł i może być użyty do tworzenia źródeł i
ujść danych, unikania wycieków pamięci w przerywanych ujść danych, unikania wycieków pamięci w przerywanych podprogramach (włączając konstruktory)podprogramach (włączając konstruktory)
w przeciwieństwie do w przeciwieństwie do auto_ptr auto_ptr bezpieczny z algorytmami i bezpieczny z algorytmami i kontenerami STLkontenerami STL
Inteligentne wskaźnikiInteligentne wskaźniki Przykład: zwykły wskaźnik a wyjątki Przykład: zwykły wskaźnik a wyjątki
X* f() X* f() { {
X* p = new X; X* p = new X;
// tu kod mogący wyrzucić wyjątek// tu kod mogący wyrzucić wyjątek
return p; return p; } }
Inteligentne wskaźnikiInteligentne wskaźniki Przykład: odpowiednik bezpieczny w przypadku wyjątkuPrzykład: odpowiednik bezpieczny w przypadku wyjątku
X* f() X* f() { {
unique_ptr<X>unique_ptr<X> p(new X); p(new X); // albo {new X} ale nie = new X // albo {new X} ale nie = new X
// tu kod mogący wyrzucić wyjątek// tu kod mogący wyrzucić wyjątek
return p.release(); return p.release(); } }
Inteligentne wskaźnikiInteligentne wskaźniki Przykład: źródło danych, bezpieczne w przypadku wyjątkuPrzykład: źródło danych, bezpieczne w przypadku wyjątku
unique_ptr<X> f() unique_ptr<X> f() { {
unique_ptr<X>unique_ptr<X> p(new X); p(new X); // albo {new X} ale nie = new X // albo {new X} ale nie = new X
// tu kod mogący wyrzucić wyjątek// tu kod mogący wyrzucić wyjątek
return p; return p; // własność jest przenoszona poza f() // własność jest przenoszona poza f()
} }
Inteligentne wskaźnikiInteligentne wskaźniki shared_ptrshared_ptr
współdzielony wskaźnik ze zliczaniem referencji do współdzielony wskaźnik ze zliczaniem referencji do wskazywanego obiektu ...wskazywanego obiektu ...
... oraz wspólną własnością obiektu przez wszystkie ... oraz wspólną własnością obiektu przez wszystkie shared_ptr shared_ptr odnoszące się do niego ...odnoszące się do niego ...
... i poprawnym działaniem w środowisku wielowątkowym... i poprawnym działaniem w środowisku wielowątkowym tworzone wskaźniki tworzone wskaźniki shared_ptrshared_ptr do tej samej danej są zliczane do tej samej danej są zliczane
w sposób szybki i prostyw sposób szybki i prosty nowy wskaźnik do określonej danej jest tworzony za pomocą innego nowy wskaźnik do określonej danej jest tworzony za pomocą innego
wskaźnika na tę daną, który już istnieje (przykład dalej)wskaźnika na tę daną, który już istnieje (przykład dalej) przy destrukcji przy destrukcji shared_ptrshared_ptr licznik referencji jest licznik referencji jest
dekrementowany dekrementowany gdy osiągnie 0 wskazywana dana jest destruowanagdy osiągnie 0 wskazywana dana jest destruowana
Inteligentne wskaźnikiInteligentne wskaźniki
void test() void test() { {
shared_ptr<int>shared_ptr<int> p1(new int); // licznik wynosi 1 p1(new int); // licznik wynosi 1 { {
shared_ptr<int>shared_ptr<int> p2(p1); // licznik wynosi 2 p2(p1); // licznik wynosi 2 { {
shared_ptr<int>shared_ptr<int> p3(p1); // licznik wynosi 3 p3(p1); // licznik wynosi 3 // licznik powraca do 2 // licznik powraca do 2
} // licznik powraca do 1 } // licznik powraca do 1 } // licznik staje sie 0 i int jest zwalniany} // licznik staje sie 0 i int jest zwalniany
Inteligentne wskaźnikiInteligentne wskaźniki shared_ptr shared_ptr wg. Stroustroup’a nie jest uniwersalnym zastępcą wg. Stroustroup’a nie jest uniwersalnym zastępcą
zwykłego wskaźnika, ze względu na poniższe koszty [1]:zwykłego wskaźnika, ze względu na poniższe koszty [1]: cykliczna struktura zbudowana z cykliczna struktura zbudowana z shared_ptrshared_ptr spowoduje wyciek przy spowoduje wyciek przy
destrukcji (któremu, kosztem dodatkowych operacji, można destrukcji (któremu, kosztem dodatkowych operacji, można przeciwdziałać, np. używając przeciwdziałać, np. używając weak_ptrweak_ptr),),
"shared ownership objects" zazwyczaj pozostają nieusunięte dłużej, niż "shared ownership objects" zazwyczaj pozostają nieusunięte dłużej, niż obiekty lokalne, powodując zwiększone zużycie zasobów,obiekty lokalne, powodując zwiększone zużycie zasobów,
mogą być kosztowne w środowisku wielowątkowym (ze względu na koszt mogą być kosztowne w środowisku wielowątkowym (ze względu na koszt unikania wyścigu danych dla licznika referencji),unikania wyścigu danych dla licznika referencji),
destruktor współdzielonego obiektu nie wykona się w przewidywalnym destruktor współdzielonego obiektu nie wykona się w przewidywalnym momencie, orazmomencie, oraz
łatwiej popełnić błąd w algorytmie/logice aktualizacji współdzielonego łatwiej popełnić błąd w algorytmie/logice aktualizacji współdzielonego obiektu, niż dla posiadanego jednokrotnie. obiektu, niż dla posiadanego jednokrotnie.
Inteligentne wskaźnikiInteligentne wskaźniki weak_ptrweak_ptr
pomocniczy wskaźnik do danych zarządzanych przez pomocniczy wskaźnik do danych zarządzanych przez shared_ptrshared_ptr;; nie posiada własności danych, przeznaczony dla nie posiada własności danych, przeznaczony dla danych posiadanych przez danych posiadanych przez shared_ptrshared_ptr
dostarcza testu czy wskazywana dana istniejedostarcza testu czy wskazywana dana istnieje posiada mechanizm blokowania/zapewnienia że na czas posiada mechanizm blokowania/zapewnienia że na czas
operacji wskazywana dana nie zostanie usuniętaoperacji wskazywana dana nie zostanie usunięta typowo nie niszczy wskazywanej danejtypowo nie niszczy wskazywanej danej
chyba że destrukcja została odłożona ze względu na blokowanie chyba że destrukcja została odłożona ze względu na blokowanie (ostatni shared_ptr do danej został usunięty gdy dana była (ostatni shared_ptr do danej został usunięty gdy dana była zablokowana), wtedy destrukcja po odblokowaniuzablokowana), wtedy destrukcja po odblokowaniu