1 / 27

Kurs języka C++ – wykład 13 (19.05.2014)

Kurs języka C++ – wykład 13 (19.05.2014). Narzędzia programistyczne w bibliotece standardowej. Spis treści. Standardowa biblioteka wzorców STL Pary i tuple Sprytne wskaźniki Ograniczenia liczbowe Minimum i maksimum Zamiana zawartości obiektów Operatory porównywania Współczynniki

tanaya
Download Presentation

Kurs języka C++ – wykład 13 (19.05.2014)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Kurs języka C++ – wykład 13 (19.05.2014) Narzędzia programistyczne w bibliotece standardowej

  2. Spis treści • Standardowa biblioteka wzorców STL • Pary i tuple • Sprytne wskaźniki • Ograniczenia liczbowe • Minimum i maksimum • Zamiana zawartości obiektów • Operatory porównywania • Współczynniki • Pomiar czasu • Funkcje lambda

  3. 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ę)

  4. STL • Biblioteka STL składa się z kilku modułów: • strumienie we/wy, • kontenery, iteratory, • algorytmy, obiekty funkcyjne, • łańcuchy, • wyrażenia regularne, • wielowątkowość i przetwarzanie współbieżne, • internacjonalizacja, • klasy narzędziowe.

  5. 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.

  6. Pary – przykłady void f(std::pair<int, const char*>); void g(std::pair<const int,std::string>); ... std::pair<int,const char*> p(46,"hello"); f(p); // OK: // calls implicitly generated copyconstructor g(p); // OK: // calls template constructor

  7. 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.

  8. Tuple – przykłady // create a four-element tuple // - elements are initialized with default value tuple<string,int,int,complex<double>> t; // create and initialize a tuple explicitly tuple<int,float,string> t1(41,6.3,"nico"); // ‘‘iterate’’ over elements: cout << get<0>(t1) << " "; cout << get<1>(t1) << " "; cout << get<2>(t1) << " "; cout << endl;

  9. Tuple – przykłady // create tuple with make_tuple() // - auto declares t2 with type of right-hand side auto t2 = make_tuple(22,44,"nico"); // assign second value in t2 to t1 get<1>(t1) = get<1>(t2); // comparison and assignment // - including type conversion if (t1 < t2) { // compares value for value t1 = t2; // OK, assigns value for value }

  10. Sprytne wskaźniki • Sprytne wskaźniki są zdefiniowane w pliku nagłówkowym <memory>. • Sprytne wskaźniki maksymalnie naśladują zwykłe wskaźniki. • Sprytne wskaźniki wspierają technikę zdobywania zasobów poprzez inicjalizację. • Wskaźnik shared_pointer<> jest wskaźnikiem ze zliczaniem referencji – współdzielony wskaźnik automatycznie niszczy swoją zawartość, jeśli nie ma już współdzielonych wskaźników odnoszących się do obiektu początkowo tworzonego dla współdzielonego wskaźnika. • Słaby wskaźnik weak_ptr<> jest referencją do wskaźnika shared_ptr<>, która może określać, czy wskaźnik shared_ptr<> był kasowany czy też nie – sam weak_ptr<> nie ma na celu zachowywanie się jak zwykły wskaźnik C++; po prostu jest obiektem i dostęp do faktycznego wskaźnika wymaga stworzenia obiektu shared_ptr<>. • Wskaźnik unique_ptr<> jest zamiennikiem przestarzałego auto_ptr<> – ma wszystkie możliwości auto_ptr<> z wyjątkiem niebezpiecznego niejawnego przenoszenia z l-wartości; wskaźnik unique_ptr<> może być stosowany z kontenerami C++11 uwzględniającymi przenoszenie.

  11. 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();

  12. 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; }

  13. 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

  14. Minimum i maksimum • Funkcjaminmax()zwraca parę elementówpair<>, gdzie pierwszy element jest minimum a drugi maksimum. • Argumentem funkcji minmax()są dwa elementy albo lista elementów; ostatnim argumentem może być metoda porównująca. • Przykład:bool int_ptr_less (int* a, int* b) { return *a < *b; }int x = 17, *px = &x;int y = 42, *py = &y;int z = 33, *pz = &z;...std::pair<int*, int*> extremes = std::minmax ({px, py, pz}, int_ptr_less);// auto extremes =// std::minmax ({px, py, pz}, // [](int*a, int*b) { return *a < *b; });

  15. Zamiana zawartości obiektów • Zamiana dwóch wartości:template <typename T>inline void swap (T &a, T &b) { T tmp(a); a = b; b = tmp; } • Można też zamieniać ze sobą tablice o określonej liczbie elementów:template <typename T, size_t N>void swap (T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))); • Przykład:int x = 33, y = 44;…std::swap(x,y);

  16. 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) { … } …}

  17. Współczynniki • W pliku nagłówkowym <ratio> jest zdefiniowany szablon do tworzenia współczynników. • Definicja tego szablonu przypomina liczbę wymierną:template <intmax_t N, intmax_t D = 1>class ratio {public: typedef ratio<num,den> type; static constexpr intmax_t num; static constexpr intmax_t den;//…}; • Licznik num i mianownik den są automatycznie redukowane do minimalnych wartości (mianownik będzie dodatni).

  18. Współczynniki – przykłady typedef ratio<25,15> FiveThirds; cout <<FiveThirds::num << "/" <<FiveThirds::den << endl; // 5/3 ratio<42,42> one; cout << one.num << "/" << one.den << endl; // 1/1 ratio<0> zero; cout << zero.num << "/" << zero.den << endl; // 0/1 typedef ratio<7,-3> Neg; cout << Neg::num << "/" << Neg::den << endl; // -7/3

  19. Współczynniki • Obliczenia na współczynnikach można wykonywać w trakcie kompilacji za pomocą następujących szablonów: ratio_add, ratio_subtract, ratio_multiply i ratio_divide (operacje arytmetyczne) oraz ratio_equal, ratio_not_equal, ratio_less, ratio_less_equal, ratio_greater i ratio_greater_equal (porównania). • Przykład:ratio_add<ratio<2,7>,ratio<2,6>>::typeratio_equal<ratio<5,3>,ratio<25,15>>::value • Istnieje też wiele predefiniowanych jednostek ratio<>: pico, nano, micro, milli, centi, deci, deca, hecto, kilo, mega, giga, tera…

  20. Pomiar czasu • Biblioteka standardowa wprowadza narzędzia pomocne do pomiaru czasu – są one zdefiniowane w pliku nagłówkowym <chrono> w przestrzeni nazw std::chrono. • Podstawowe pojęcia: punkt czasowy (ang. timepoint), przedział czasowy (ang. duration), epoka – punkt bieżący zegara (ang. epoch).

  21. Pomiar czasu • Przedział czasowy reprezentowany przez szablon std::chrono::duration<> jest liczbą określonych jednostek czasowych (mierzonych w sekundach). • Przykłady:std::chrono::duration<int> twentySeconds(20);std::chrono::duration<double,std::ratio<60>>halfAMinute(0.5);std::chrono::duration<long,std::ratio<1,1000>> oneMillisecond(1); • W bibliotece standardowej zdefiniowano następujące typy przedziałów czasowych: nanoseconds, microseconds, milliseconds, seconds, minutes i hours. • Przykłady:std::chrono::seconds twentySeconds(20);std::chrono::hours aDay(24);

  22. Pomiar czasu • Przedziały czasowe możemy porównywać, dodawać, odejmować, mnożyć i dzielić przez współczynniki oraz inkrementować i dekrementować o określoną jednostkę. • Przykład:chrono::duration<int,ratio<1,3>> d1(1); // 1/3 sekundychrono::duration<int,ratio<1,5>> d2(1); // 1/5 sekundyd1 + d2 /* 8 jednostek z 1/15 sekundy */d1 < d2 /* false */

  23. Pomiar czasu • Zegar definiuje epokę i długość tyknięcia zegara. • W bibliotece standardowej zdefiniowane są trzy zegary: system_clock (z funkcjami to_time_t() oraz from_time_t()), steady_clock (nigdy nie korygowany) i high_resolution_clock (dokładny zegar systemowy). • Bieżący czas można uzyskać za pomocą metody now():auto system_start = chrono::system_clock::now(); • Sprawdzenie czy upłynęła co najmniej minuta do startu:if (system_clock::now() > system_start + minutes(1))

  24. Pomiar czasu • Punkt czasowy jest reprezentowany przez obiekt time_point. • Pomiaru czasu można dokonać za pomocą punktów czasowych:auto t = steady_clock::now();// ... do something ...auto d = steady_clock::now()−t; • Konwersja punktu czasowego do postaci kalendarzowej: std::string asString (const std::chrono::system_clock::time_point&tp) {// convert to system time:std::time_t t = std::chrono::system_clock::to_time_t(tp);std::string ts = std::ctime(&t); // convert to calendar timets.resize(ts.size()-1); // skip trailing newlinereturn ts;}

  25. Funkcje lambda • Programista często chciałby zdefiniować predykatowe funkcje w pobliżu wywołań takich funkcji, jak na przykład pochodzących ze standardowej biblioteki <algorithm> (szczególnie sort i find) – oczywistym rozwiązaniem jest zdefiniowanie w takim miejscu funkcji lambda (określanej też jako lambda-wyrażenie). • Funkcje lambda to anonimowe obiekty funkcyjne. • Główne zastosowanie funkcji lambda to ich użycie jako argumentu sterującego obliczeniami w innych funkcjach. • Przykład:[](int x, int y) { return x + y; }

  26. Funkcje lambda • Funkcja lambda określa typ zwracanego wyniku za pomocą frazy -> TYP. • Przykład:[](int x, int y) -> int{int z = x * x; return z + y + 1;} • Jeśli ciało funkcji lambda składa się z jednej instrukcji return, to typ zwracanego wyniku będzie wydedukowany za pomocą decltype(). • Przykład:[](int x, int y) // -> decltype(x*x+y+1){return x * x + y + 1;}

  27. Funkcje lambda • …

More Related