Metaprogramowanie. C++ - szablony. Metaprogramowanie. Metaprogramowanie. Metaprogramowanie. Metaprogramowanie. Metaprogramowanie

Wielkość: px
Rozpocząć pokaz od strony:

Download "Metaprogramowanie. C++ - szablony. Metaprogramowanie. Metaprogramowanie. Metaprogramowanie. Metaprogramowanie. Metaprogramowanie"

Transkrypt

1 C++ - szablony Tworzenie programów, które w wyniku działania dostarczają kodów źródłowych (innych programów). Narzędziem jest preprocesor oraz mechanizm szablonów: dostarczają instrukcji pozwalających na manipulowanie kodem źródłowym. Algorytm jest wykonywany w trakcie kompilacji. 180 template <unsigned n> struct Silnia { static const unsigned value = n*silnia<n-1>::value; template<> struct Silnia<0> { // specjalizacja jawna static const unsigned value = 1; int main() { int i = Silnia<5>::value; cout << i; return 0; Tworzenie metaprogramów może dawać mało czytelny kod (czasami). Używanie metaprogramów daje z reguły bardziej czytelny i elastyczny kod. Metaprogramy wykorzystują jedynie byty dostępne w czasie kompilacji (stałe całkowite, typy, itd.), dlatego rekurencja jest powszechna w tych programach (nie można tworzyć zmiennych ani pętli) template <unsigned n> inline double pow(double x) { return x* pow<n-1>(x); template<> inline double pow<0>(double x) { return 1.0; int main() { double b = 3.14; double a = pow<3>(b); cout << a; return 0; Szablon pow : skraca zapis, zwiększa czytelność kodu oraz jego szybkość. Ale.. Jeżeli wykładnik jest dużą liczbą całkowitą, to utworzona przez szablon pow funkcja jest długa, wielkość kodu wynikowego wzrasta. Ulepszenie: w szablonach można implementować złożenia funkcji. Np. x n dla n=2 m można wykonać jako m-krotne podnoszenie do kwadratu. Dla n=1024 to daje (tylko) 10 operacji podnoszenia do kwadratu

2 Potęga dowolnej liczby całkowitej dodatniej - pomysł: 1. Zapisać wykładnik n binarnie, np.: n=19, to: B = [ ] gdzie n = b m 2 m + b m-1 2 m-1 + b m-2 2 m b Stąd dla przykładowej wartości 19: n = b b b Wtedy x n jest iloczynem składników x^(2 m ), np.: x 19 = x tj.: (((x 2 ) 2 ) 2 ) 2 *x 2 *x a tego właśnie potrzebowaliśmy. template <unsigned n> double Power(double x) { return Power<2>(Power<n/2>(x)) * Power<n%2>(x); template<> double Power<2>(double x) { return x*x; template<> double Power<1>(double x) { return x; template<> double Power<0>(double x) { return 1; /// double c = Power<19>(b); n=19: P<2>(P<9>(x)) P<1>(x) n=9: P<2>(P<4>(x)) P<1>(x) n=4: P<2>(P<2>(x)) P<2>(x) = x 2 P<1>(x) = x Stąd: (((x 2 ) 2 ) 2 x) 2 x X 19 = x 16 x 2 x Metaprogramy mogą dostarczać przybliżenia wartości funkcji matematycznych z założoną dokładnością. funkcja wykładnicza e x = 1 + 1! + 2! + 3! +, < < tzw. szereg Taylora. Funkcja wykładnicza z zadaną dokładnością przykład: template <unsigned int N> inline double Exp(double x) { return Exp<N-1>(x)+Power<N>(x)/Silnia<N>::value; template <> inline double Exp<0>(double x) { return 1.0; // double d = Exp<5>(a); Możemy dostarczyć szablonu, który będzie generował wyrażenie zawierające początkowe wyrazy tego szeregu Kolekcje typów Kolekcja pozwala opisać zestaw typów, dla których będziemy wykonywać jakieś przetwarzanie (np. generować metodę). Przykład kolekcji: template <class H, class T> struct TList { typedef H Head; typedef T Tail; struct NullType { Lista przechowująca trzy typy: short, int oraz long: typedef TList<short, TList<int, TList<long, NullType>>> Integers; 189 Tworzenie list za pomocą Tlist nie jest wygodne: należy rekurencyjnie zagłębiać szablony. Rozszerzenie tej konstrukcji: template <class T0, class T1, class T2> struct TListCreator { typedef TList< T0, typename TListCreator<T1,T2,NullType>::type> type; template <> struct TListCreator<NullType, NullType, NullType> { typedef NullType type; typedef TListCreator <short, int, long>::type Integers2; Wynikiem rozszerzenia jest type: przechowuje listę typów. Szablon z przykładu powyżej pozwala na listę od 0 do 3 elementów

3 Dla kolekcji typów dostarcza się operacji, które pozwalają wykorzystywać te kolekcje w programach. Aby ustalić rozmiar listy typów: template <class TL> struct Size { static const int value = Size <typename TL::Tail>::value+1; template <> struct Size<NullType> { static const int value = 0; int k = Size<Integers2>::value; template <class H, class T> struct TList { typedef H Head; typedef T Tail; Dla kolekcji typów dostarcza się operacji, które pozwalają wykorzystywać te kolekcje w programach. Aby uzyskać typ dla danego indeksu: template <class TL, int n> struct GetTypeAt { typedef typename GetTypeAt<typename TL::Tail, n-1>::type type; template <int n> struct GetTypeAt<NullType, n> { typedef NullType type; // koniec, gdy koniec listy template <class TL> struct GetTypeAt<TL, 0> { typedef typename TL::Head type; // koniec, gdy właściwy typ // GetTypeAt<Integers2,1>::type k = Size<Integers2>::value; // int C++11 Lista rozszerzeń C++11 obecnych w VC2010: C++ 11 wybrane elementy 1. Referencje do rvalue, 2. Pętla for oparta na zakresie, 3. Dedukcja typów danych, 4. Sprytne wskaźniki, 5. nullptr 6. Kontenery mieszające (kontenery z haszowaniem). 194 C++11: referencje do rvalue C++ 11: Referencje do rvalue lvalue i rvalue lvalue - wyrażenie które odnosi się do obszaru pamięci i pozwala na pozyskanie adresu tego obszaru za pomocą operatora & rvalue - wyrażenie nie będące lvalue: int foobar(); int j = 0; j = foobar(); // ok, foobar() jest rvalue int* p2 = &foobar(); // błąd, nie można pobrać adresu j = 42; // ok, 42 jest rvalue 196 3

4 C++11: referencje do rvalue Przykładowy problem Przyjmijmy, że mamy klasę w której jedno z pól jest wskaźnikiem m_presource np. do pewnego kontenera. Przeciążony operator kopiowania dla tej klasy: X& X::operator=(X const & rhs) { // [...] // zniszcz zasób wskazywany przez m_presource // sklonuj to, na co wskazuje rhs.m_presource // dołącz klon do m_presource. // [...] Teraz można wywołać kod: X foo(); X x; x = foo(); // wywołanie przeciążonego operatora przypisania C++11: referencje do rvalue Przykładowy problem (move semantics) Zdecydowanie mniejszy nakład pracy dałby taki przeciążony operator: // [...] // swap ( m_presource, rhs.m_presource ) // [...] To jest właśnie move semantics. Żeby to zadziałało, potrzebujemy, aby argument operatora był referencją. Jeżeli argument jest lvalue nie ma problemu. A jeżeli argument jest rvalue?.... wtedy przydałby się drugi referencyjny typ danych, który byłby wypierany, kiedy argumentem jest rvalue C++11: referencje do rvalue C++11: referencje do rvalue Przykładowy problem (move semantics) Rozwiązanie: Przykładowy problem (move semantics) Rozwiązanie dla przeciążonego operatora przypisania: void foo(x& x) {.. void foo(x&& x) {.. X x; X foobar() {.. ; return..; // referencja do lvalue // referencja do rvalue foo(x); // argument jest lvalue: wywołuje foo(x&) foo(foobar()); // argument jest rvalue: wywołuje foo(x&&) Na etapie kompilacji rozstrzyga się, jaki argument zostanie podany w wywołaniu. X& X::operator=(X const & rhs); // klasyczna implementacja X& X::operator=(X&& rhs) { // Move semantics: zamiana zawartości pomiędzy this i rhs //.. return *this; Uwaga: tak, to prawda, że && można stosować w dowolnej funkcji, ale przyjmuje się stosowanie wyłącznie do przeciążonych operatorów przypisania i konstruktorów kopiujących C++11: referencje do rvalue Move semantics Czy zmienna referencyjna do rvalue jest traktowana jako rvalue? void foo(x&& x) { X anotherx = x; // który operator przypisania zadziała? //... (x jest referencją do rvalue, więc powinien operator=(x&& x)..) Nie. Rzeczy zadeklarowane jako rvalue mogą być lvalue lub rvalue. Prosta zasada mówi: jeżeli coś ma nazwę, to jest lvalue. W przeciwnym razie jest rvalue. C++ 11: Pętla for oparta na zakresie 201 4

5 C++11: pętla for oparta na zakresie Nowa składnia pętli for for ( deklaracja : wyrażenie ) instrukcje wyrażenie tablica, obiekt implementujący semantykę kontenera (zwraca obiekt w stylu iteratora za pomocą metod begin i end) deklaracja zmiennej - typu takiego jak elementy w tablicy lub kontenerze instrukcje wykonywane tyle razy, ile elementów przechowuje tablica lub kontener vector<int> vec; vec.push_back( 10 ); vec.push_back( 20 ); C++11: pętla for oparta na zakresie Przykłady Modyfikowanie zawartości kontenera: vector<int> vec; vec.push_back( 1 ); vec.push_back( 2 ); for (int& i : vec ) { i++; // inkrementuje wartości z wektora for (int i : vec ) { cout << i; UKSW, WMP. SNS, Warszawa C++11: pętla for oparta na zakresie Obiekty posiadające zakres to: wszelkie kontenery z biblioteki STL, ponieważ: 1. posiadają iteratory, które wspierają metody operator*, operator!= i operator++ (zadeklarowane jako metody własne albo jako funkcje globalne), 2. posiadają metody begin i end (zadeklarowane jako metody własne albo jako funkcje globalne), zwracające iteratory na początek i koniec kontenera. wszelkie inne obiekty zaimplementowane samemu o funkcjonalności kontenerów STL (obowiązkowa w/w funkcjonalność). C++ 11: Dedukcja typów danych 205 Mechanizmy dedukcji typów danych Pochodzący C++98: 1. Szablony i ich parametry Wprowadzone w C++11: 1. auto 2. decltype Pozwalają uniknąć ciągłego wypisywania typów, które są oczywiste bądź powtarzają się. Zmiana typu zmiennej w jednym miejscu kodu propaguje się na cały kod (kompilator sam dedukuje nowy typ danych uwaga: może nas zaskoczyć). 207 Zasady dedukcji dla auto Podobne do zasad dedukcji dla parametrów szablonu z C++98 Deklarując auto jako typ zmiennej auto x = 10; auto odgrywa rolę taką, jak parametr T w szablonie: template <typename T> void fun(t x) ; fun(10); Stąd: const char name[] = "ABC"; // name: const char[13] auto arr1 = name; // arr1: const char* void Fun(int, double); auto func1 = somefunc; // Fun: void(int, double) // func1: void (*)(int, double) 208 5

6 Pożytek z auto Mamy szablon funkcji, która na pewnym zakresie elementów kontenera identyfikowanym przez parę iteratorów, wykonuje czynności ważne i potrzebne : template<typename It> // wykonuje czynności ważne i potrzebne void czwip(it b, It e) // na rzecz elementów od 'b' do 'e' { for (; b!= e; ++b) { typename std::iterator_traits<it>::value_type currvalue = *b;... Odwołujemy się pracowicie do cech charakterystycznych iteratora, żeby pozyskać typ danych wskazywanych przez te iteratory. Pożytek z auto Mamy szablon funkcji, która na pewnym zakresie elementów kontenera identyfikowanym przez parę iteratorów, wykonuje czynności ważne i potrzebne : template<typename It> // wykonuje czynności ważne i potrzebne void czwip(it b, It e) // na rzecz elementów od 'b' do 'e' { for (; b!= e; ++b) { auto currvalue = *b;... Wersja dla mniej pracowitych Pożytek z auto Jeszcze jeden przykład dla mniej pracowitych : map<string, string> address_book; for ( auto address_entry : address_book ) { cout << address_entry.first << " < " << address_entry.second << ">" << endl; Pożytek z auto Pozyskanie rozmiaru kontenera: std::vector<int> v;... unsigned sz = v.size(); Co prawda typ zwracany przez.size() to: vector<int>::size_type ale wszyscy wiedzą, że to typ całkowity bez znaku, więc spotyka się unsigned. Nie wszyscy jednak wiedzą, że choć w Win32 zmienne tych dwóch typów zajmują te samą liczbę bajtów, to już w Win64 nie (unsigned zajmuje mniej).. Rekompilacja kodu na Win64 powiedzie się, ale dla dostatecznie dużych zbiorów danych działanie może przestać być poprawne. Dlatego prościej i bezpieczniej pisać: auto sz = v.size(); Niespodzianki z auto mamy funkcję, która dla widgetów zwraca wektor opisujący ich cechy, tj. co potrafią, a czego nie: std::vector<bool> cechy(const Widget& w); Kod programu: Widget w;... bool cecha5 = cechy(w)[5]; // czy posiada cechę nr 5.. A gdyby tak napisać: auto cecha5 = cechy(w)[5]; // czy posiada cechę nr 5 Niespodzianki z auto Dla: auto cecha5 = cechy(w)[5]; Typ zmiennej cecha5 to vector<bool>::reference (klasa zagnieżdżona w vector<bool>). Powód jest natury technicznej: klasa vector<bool> została tak zaprojektowana, aby przechowywać wartości w postaci spakowanej jeden bit na każdy element (a w C++ nie ma referencji do pojedynczych bitów). Stąd operator[] dla vector<bool> zwraca obiekt, który działa tak jak bool& Oczywiście, wśród jego wielu funkcjonalności, istnieje też możliwość konwersji tego obiektu do bool. Powinno działać tak samo

7 Niespodzianki z auto Dla: auto cecha5 = cechy(w)[5]; Typ zmiennej cecha5 to vector<bool>::reference (klasa zagnieżdżona w vector<bool>). Teraz zmienna cecha5 jest kopią obiektu przechowującego referencję do właściwej informacji bitu nr 5. Niestety, funkcja cechy zwraca referencja do obiektu, który za chwilę zniknie (funkcja cechy zwraca kontener obiekt tymczasowy, więc jego elementy też są tymczasowe..). Dlatego cecha5 będzie przechowywać referencję do obiektu, który nie istnieje. Niespodzianki z auto Klasa: vector<bool>::reference to tzw. klasa proxy (proxy class). Takich klas jest wiele. Przestroga: należy unikać sytuacji w kodzie, gdzie: auto pewnazmienna = wyrażenie typu klasa proxy ; No tak, tylko że one zostały tak napisane, żeby być jak najmniej widoczne (w założeniu: mają być całkiem niewidoczne). Aby się nie dać oszukać, należy: sprawdzać nagłówki funkcji i metod (np. w źródłach bibliotek), albo.. auto cecha5 = static_cast<bool>(cechy(w)[5]); Dedukcja typu przez decltype zwraca typ zmiennej lub wyrażenia podanego w argumencie: const int i = 0; bool f(const Widget& w); // decltype(i): const int // decltype(w): const Widget& // decltype(f): bool(const Widget&) struct Point { int x, y; // decltype(point::x): int // decltype(point::y): int Widget w; // decltype(w): Widget Dedukcja typu przez decltype Przydaje się szczególnie kiedy szablon funkcji ma zwrócić typ danych zależny od typu parametru (ale nie będący typem parametru) funkcja zwracająca element z kontenera po uprzedniej autoryzacji dostępu do danych dla bieżącego użytkownika: template<typename Container, typename Index> (?) authandaccess(container& c, Index i) { Funkcja powinna zwracać typ taki, jak ma c[i] if (f(w)) // decltype(f(w)): bool Jak go pozyskać? Dedukcja typu przez decltype Dygresja: W C++11 wprowadzono możliwość podania typu zwracanego przez funkcję w miejscu tuż za jej nagłówkiem (tzw. trailing return type); bardzo przydatne, kiedy typ zwracanych danych ma skomplikowany zapis, np. : auto fpif(int) -> int(*)(int) Drugie zastosowanie trt kiedy zwracany typ zależy argumentów wywołania: template<typename Container, typename Index> auto authandaccess(container& c, Index i) -> decltype(c[i]) { authenticateuser(); // autoryzacja dostępu return c[i]; // dostęp do danych C++ 11: Sprytne wskaźniki 219 7

8 Kontrola zmiennych dynamicznych TR1 dostarcza pary szablonów: 1. shared_ptr 2. weak_ptr Ich zadanie: zaalokowane zasoby są dostępne tak długo, póki są potrzebne, ale nie dłużej. Kontrola zmiennych dynamicznych Obiekt typu shared_ptr<ty> Przechowuje wskaźnik do obiektu typu Ty. Jeżeli wskaźnik jest różny od NULL, do zaalokowanego zasobu mamy dostęp operatorami: operator-> oraz operator*. Obiekt typu shared_ptr<ty> przechowuje też licznik odwołań do zasobu. Kiedy kopiujemy obiekt, licznik jest inkrementowany. Kiedy usuwamy kopie, licznik jest dekrementowany. Kiedy licznik schodzi do zera, zasób jest zwalniany Kontrola zmiennych dynamicznych Obiekt typu weak_ptr<ty> Przechowuje wskaźnik do obiektu typu Ty. Jeżeli wskaźnik jest różny od NULL, do zaalokowanego zasobu mamy dostęp operatorami: operator-> oraz operator*. Obiekt typu weak_ptr<ty> nie przechowuje licznika odwołań do zasobu. Mimo to, też się bardzo przydaje. 223 Kontrola zmiennych dynamicznych shared_ptr posiada zasób, jeżeli: 1. Został utworzony z argumentem zawierającym wskaźnik do zasobu, 2. Został utworzony jako kopia obiektu posiadającego ten zasób, 3. Został utworzony z obiektu weak_ptr, który wskazywał na ten zasób, 4. Posiadanie zostało mu przypisane w wyniku użycia operator= lub reset. W tym przypadku przestaje posiadać poprzedni zasób, o ile taki posiadał. weak_ptr wskazuje na zasób, jeżeli: 1. Został utworzony z obiektu shared_ptr, który wskazywał na ten zasób, 2. Został utworzony z obiektu weak_ptr, który wskazywał na ten zasób, 3. Posiadanie zostało mu przypisane w wyniku użycia operator=. W tym przypadku przestaje posiadać poprzedni zasób, o ile taki posiadał. 224 Kontrola zmiennych dynamicznych Obiektowi można przypisać kontrolę nad zasobem lub uczynić pustym. Obiekt traci kontrolę nad zasobem, kiedy przypisywana mu jest kontrola nad innym zasobem, albo kiedy jest usuwany. Kiedy ostatni obiekt typu shared_ptr, posiadający pewien zasób, jest usuwany, zasób jest zwalniany. Jeżeli się tak stanie, wszystkie obiekty typu weak_ptr, które wskazywały na ten zasób, tracą ważność (expire). Kontrolowany zasób ma swój usuwacz (has a deleter) jeżeli jego oryginalny właściciel otrzymał ten zasób za pomocą funkcji wywołanej ze wskaźnikiem na zasób oraz na obiekt usuwacza. Kontrola zmiennych dynamicznych przykłady: Deklaracja obiektu reprezentującego sprytny wskaźnik: #include <memory> struct resource { // przykładowa struktura do alokacji resource(int i0 = 0) : i(i0) { int i; int main() { shared_ptr<int> sp; // konstruktor domyślny daje pusty obiekt shared_ptr<resource> sp(new resource(3));

9 Kontrola zmiennych dynamicznych przykłady: Dostarczenie usuwacza: struct deleter { void operator()(resource *res) { cout << "destroying resource at " << (void*)res << '\n'; delete res; int main() { shared_ptr<resource> sp(new resource(3), deleter()); Kontrola zmiennych dynamicznych przykłady: Kopiowanie: Uwaga: nie należy używać tego samego zasobu przy tworzeniu dwóch różnych sprytnych wskaźników, bo destruktor też będzie użyty dwa razy raczej: jeden utworzyć j.w., drugi za pomocą konstruktora kopiującego z tego pierwszego. shared_ptr<resource> sp0(new resource(4)); // sp0 przechowuje wskaźnik na zasób shared_ptr<resource> sp1(sp0); // sp1 udostępnia ten sam zasób Kontrola zmiennych dynamicznych przykłady: Dostęp do zasobu: int *ip = new int(3); // alokowanie zasobu typu int cout << (void*)ip << '\n'; // pokazanie adresu shared_ptr<int> sp(ip); // tworzenie obiektu shared_ptr cout << (void*)sp.get() << '\n'; // pokazanie przechowywanego adresu cout << *sp << '\n'; cout << (void*)&*sp << '\n'; // pokazanie przechowywanej wartości // pokazanie adresu wartości Kontrola zmiennych dynamicznych przykłady: Dostęp do pól zasobu typu strukturalnego: struct S { int member; int main() { S *s = new S; // tworzenie obiektu typu S s->member = 4; // przypisanie do member shared_ptr<s> sp(s); // tworzenie obiektu shared_ptr if (sp) // konwersja na bool (przydatna!) cout << sp->member << '\n'; // pokazanie wartości member Kontrola zmiennych dynamicznych przykłady: Liczenie sprytnych wskaźników odnoszących się do jednego zasobu: spi sp0; // pusty obiekt cout << "empty object: " << sp0.use_count() << '\n'; spi sp1((int*)0); // żadnego zasobu, ale niepusty cout << "null pointer: " << sp1.use_count() << '\n'; spi sp2(new int); // posiada zasób cout << sp2.unique() << '\n'; // zwraca true jedyny właściciel cout << "one object: " << sp2.use_count() << '\n'; { // tworzymy krótko żyjący obiekt sp3 spi sp3(sp2); // kopiowanie cout << "two objects: " << sp2.use_count() << '\n'; cout << sp2.unique() << '\n'; // false - dwóch właścicieli // sp3 usunięty cout << "one object: " << sp2.use_count() << '\n'; 231 Kontrola zmiennych dynamicznych przykłady: Przekazywanie i zwalnianie zasobów: sps sp0(new resource(1)); // alokacja i przypisanie zasobu sps sp1(new resource(2)); // alokacja i przypisanie zasobu sps sp2(sp0); // przypisanie zasobu sp1 = sp0; // przypisanie zasobu i zwolnienie zasobu sp2.reset(); // zwolnienie zasobu sp0.swap(sp2); // zamiana przypisań zasobów if(sp0 == sp1) cout << "Nie jest dobrze." if(sp0!= sp1) cout << "Jest dobrze." 232 9

10 #include <algorithm> #include <memory> #include <iostream> #include <set> using namespace std; Kontrola zmiennych dynamicznych przykłady: Operator porównania mniejszy-niż i zastosowanie z kontenerem: typedef shared_ptr<int> spi; typedef set<spi> iset; typedef iset::const_iterator citer; static void lookup(const iset& data, spi sp) { // szuka obiektu pasującego do sp citer res = lower_bound(data.begin(), data.end(), sp); cout << *sp; if (res == data.end() *res!= sp) cout << " nie ma.\n"; else cout << " jest.\n"; Kontrola zmiennych dynamicznych przykłady: Operator porównania mniejszy-niż i zastosowanie z kontenerem: iset data; // kontener (pusty) spi sp0(new int(0)); spi sp1(new int(1)); spi sp2(new int(2)); spi sp3(sp1); // dzielenie własności z sp1 spi sp4(new int(1)); // taka sama wartość jak sp1, ale inny zasób data.insert(sp0); data.insert(sp1); data.insert(sp2); lookup(data, sp1); // szukamy sp1 - sukces lookup(data, sp3); // szukamy sp3 - sukces lookup(data, sp4); // szukamy sp4 -? Kontrola zmiennych dynamicznych weak_ptr: Obiekty tego typu przydatne są do przerywania cykli w strukturach danych. Cykl występuje gdy dwa lub więcej kontrolowanych zasobów przechowują wskaźniki na siebie nawzajem, tak że tworzą one pętlę. Np. jeżeli element head zawiera pole typu shared_ptr, który wskazuje na inny element N1, który zawiera pole shared_ptr, wskazujące na head, to takie dwa elementy tworzą pętlę. Ponieważ takie dwa elementy wskazują na siebie nawzajem, żaden nie będzie miał nigdy licznika wskazań o wartości zero. Dlatego nigdy nie zostaną usunięte, nawet, jeżeli nikt na nich nie będzie już wskazywał. Aby to zmienić N1 powinien zawierać pole typu weak_ptr, wskazujące na head. 235 Kontrola zmiennych dynamicznych weak_ptr: Jeżeli N1 zawiera pole typu weak_ptr, wskazujące na head, to: 1. Nadal można sięgnąć do head z N1. 2. Kiedy ostatni shared_ptr wskazujący na head zostanie usunięty, licznik wskazań na head będzie równy zero i head zostanie usunięty. 3. Destruktor head usunie również shared_ptr wskazujący na N1 wtedy licznik wskazań na N1 będzie równy zero i N1 też zostanie usunięty. struct node { // struct do demonstracji cykli shared_ptr<node> next; weak_ptr<node> weak_next; 236 Kontrola zmiennych dynamicznych weak_ptr: Przykład struktury danych z cyklem i bez cyklu: node *head = new node; node *N1 = new node; shared_ptr<node> root(head); head->next = shared_ptr<node>(n1); N1->next = root; N1->weak_next = root; // cykl! // nie ma cyklu! Kontrola zmiennych dynamicznych weak_ptr: Przykład utraty ważności wskaźnika: cout << boolalpha; shared_ptr<resource> sp(new resource); weak_ptr<resource> wp(sp); cout << "wskazuje na zasób: " << wp.expired() << '\n'; cout << "liczba posiadaczy zasobu: " << wp.use_count() << '\n'; sp.reset(); cout << "stracił ważność: " << wp.expired() << '\n';

11 C++11: nullptr Zerowanie wskaźnika Do wyzerowania wskaźnika posługujemy się NULL bądź 0. C++ 11: nullptr To są liczby. Stąd może pojawić się niejednoznaczność: void fun(int); // trzy przeciążenia fun void fun(bool); void fun(void*); f(0); f(null); Dlatego w C++11 wprowadzony został nullptr. // wywoła f(int), nie f(void*) // wywoła f(int), nigdy f(void*) 240 C++11: nullptr Zerowanie wskaźnika nullptr nie jest typem całkowitoliczbowym. Działa, jakby był wskaźnikiem na każdy dowolny typ (taka magia..) C++11: nullptr Zerowanie wskaźnika nullptr nie jest typem całkowitoliczbowym. Działa, jakby był wskaźnikiem na każdy dowolny typ (taka magia..) f(nullptr); // wywoła f(void*) f(nullptr); // wywoła f(void*) Pomaga ujednoznacznić kod: auto result = findrecord( /* argumenty */ ); if (result == 0) {... Jakiego typu będzie result? Pomaga ujednoznacznić kod: auto result = findrecord( /* argumenty */ ); if (result == nullptr) {... Jakiego typu będzie result? C++11: nullptr C++11: nullptr class Widget { auto result1 = Call(f1, 0); // 'int (Widget *)' : cannot convert parameter 1 from 'int' to 'Widget *' int f1(widget* pw) { return 0; double f2(widget* pw) { return 0.0; bool f3(widget* pw) { return true; template<typename FuncType, typename PtrType> auto Call(FuncType func, PtrType ptr) -> decltype(func(ptr)) { return func(ptr); auto result2 = Call(f2, NULL); // 'double (Widget *)' : cannot convert parameter 1 from 'int' to 'Widget * auto result3 = Call(f3, nullptr); // działa!

12 C++ 11: Wyrażenia lambda Obiekty wywoływalne (callables): W C++98 predykaty logiczne i funktory arytmetyczne, przekazywane jako jeden z argumentów przy wywołaniu algorytmu, można było tworzyć na podstawie: 1. Funkcji (lub wskaźników do funkcji) o ustalonej, pasującej do potrzeb algorytmu liczbie argumentów 2. Obiektów klas wywoływalnych (z przeciążonym operatorem wywołania obiektu) W C++11 dochodzą jeszcze wyrażenia lambda: - Wywoływalny kawałek kodu (funkcja inline, bez własnej nazwy) - Mają zdefiniowany typ zwracanej wartości, argumenty wywołania i kod wykonywalny, można je definiować wewnątrz innych funkcji. 246 Wyrażenie lambda budowa: [capture list] (parameter list) -> return type { function body gdzie: capture list lista lokalnych zmiennych zadeklarowanych w otoczeniu parameter list lista parametrów wywołania return type typ zwracanych danych function body wykonywalny kod funkcji Uwaga: typ zwracanych danych jest deklarowany w miejscu tuż za nagłówkiem z wykorzystaniem strzałki -> (tj. wg notacji trailing return type); 247 Wyrażenie lambda budowa: [capture list] (parameter list) -> return type { function body Można pominąć listę parametrów oraz informację o typie zwracanych danych, ale muszą wystąpić: lista lokalnych zmiennych oraz kod wykonywalny, np.: auto f = [] { return 42; f obiekt wywoływalny, który nie przyjmuje żadnych argumentów i zwraca 42. Wywołanie jest identyczne jak w przypadku funkcji: cout << f() << endl; // wypisuje w oknie konsoli 42 Pominięcie informacji o typie zwracanych danych: typ zwracany to void, lub jeżeli kod zawiera tylko return, to typ jest dedukowany na tej podstawie. 248 Wyrażenie lambda z argumentami: porównanie długości dwóch napisów [](const string &a, const string &b) { return a.size() < b.size(); Argumentom nie można przypisywać wartości domyślnych. Przykład wykorzystania wywołanie algorytmu sortującego słowa w kontenerze words, z wykorzystaniem predykatu zdefiniowanego w postaci lambdy : stable_sort(words.begin(), words.end(), [](const string &a, const string &b) { return a.size() < b.size();); Przechwytywane zmienne lista: [ ] lista przechwyconych wartości jest pusta, kod wyrażenia lambda używa tylko tego, co zostało przekazane w argumentach wywołania [nazwa1, &nazwa2,..] lista zmiennych lokalnych przechwyconych domyślnie przez wartość; jeżeli przed nazwą stoi symbol &, to następuje przechwycenie przez referencję

13 Wyrażenie lambda z listą lokalnych zmiennych przechwyconych przez wartość: sprawdzenie, czy długość jest większa od wartości przechowywanej w zmiennej sz: [sz](const string &a) { return a.size() >= sz; W kodzie wyrażenia lambda można odwoływać się tylko do tych zmiennych dostępnych lokalnie w otoczeniu wyrażenia, które zostały zadeklarowane w liście lokalnych zmiennych. Przykład wykorzystania znalezienie w kontenerze words pierwszego słowa o długości równej lub większej niż sz: auto wc = find_if(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; ); 251 Wyrażenie lambda i zmienne globalne: Po znalezieniu pierwszego słowa o odpowiedniej długości, możemy następnie wypisać wszystkie słowa, które po nim występują: for_each(wc, words.end(), [](const string &s){cout << s << " ";); cout << endl; Uwaga: mimo, że lista zmiennych lokalnych jest pusta, kod korzysta z cout (?) 1. Lista lokalnych zmiennych służy do przekazania do kodu wyrażenia wyłącznie zmiennych lokalnych non-static. 2. Zmienne zdefiniowane poza funkcją, gdzie wywołana została lambda, ale dostępne wewnątrz tej funkcji, są również dostępne w kodzie lambda. 252 Obiekt lambda: 1. Kiedy przekazujemy wyrażenie lambda do funkcji, tworzymy nowa klasę oraz obiekt tej klasy, którym będzie argument wywołania tej funkcji. 2. Odpowiednio, kiedy używamy auto, żeby zdefiniować zmienną zainicjalizowaną wyrażeniem lambda, zmienna ta jest obiektem nowo utworzonej klasy. 3. Klasa utworzona z wyrażenia lambda posiada listę pól odpowiadających przechwyconym zmiennym; są one inicjalizowane, kiedy obiekt jest tworzony. 253 Obiekt lambda: auto wc = find_if(words.begin(), words.end(), [sz](const string &a) { return a.size() >= sz; ); wygeneruje klasę, która będzie wyglądała tak, jak klasa SizeComp poniżej: class SizeComp { SizeComp(size_t n): sz(n) { // każdy kolejny parametr // konstruktora odpowiada jednej przechwytywanej zmiennej; // operator wywołania, który zwraca daną takiego samego // typu, ma takie same parametry i kod jak wyrażenie lambda bool operator()(const string &a) const { return a.size() >= sz; private: size_t sz; // pola odpowiadają przechwytywanym zmiennym 254 Przechwytywanie zmiennych: Zmienne lokalne przechwycone przez wyrażenie mogą zostać przechwycone w trybie przez referencję bądź przez wartość. W przykładach dotychczas przez wartość: void fcn1() { size_t v1 = 42; // zmienna lokalna auto f = [v1]{ return v1; // kopiowanie v1 do obiektu v1 = 0; auto j = f(); // j==42 ponieważ f przechowuje kopię v1 Zmienne przechwycone przez referencję: void fcn2() { size_t v1 = 42; // zmienna lokalna // obiekt f2 przechowuje referencję do v1 auto f2 = [&v1] { return v1; v1 = 0; auto j = f2(); // j==0 ponieważ f2 ma referencję do v1 Uwaga: kiedy przechwytujemy obiekt przez referencję, musimy być pewni, że będzie nadal istniał w momencie działania kodu wyrażenia lambda

14 Zmienne przechwycone przez referencję: Przykład, kiedy przechwycenie przez referencję jest konieczne: void funwords(vector<string> &words, vector<string>::size_type sz, ostream &os = cout, char c = ' ') { // tutaj kod, który np. porządkuje słowa // wg określonego kryterium // a teraz kod który je wypisuje do strumienia // podanego w argumencie wywołania funkcji 'funwords' for_each(words.begin(), words.end(), [&os, c](const string &s) { os << s << c; ); 257 Zmienne przechwycone przez referencję - podsumowanie: Zmienne typów bazowych int, double najprościej przechwytywać w obiekcie lambda w trybie przez wartość. Kiedy przechwytujemy w trybie przez referencję, np. iteratory, lub wskaźniki, należy zapewnić istnienie wskazywanych struktur danych, kiedy obiekt lambda będzie wykonywany, oraz zapewnić, że zawartość będzie taka, jakiej oczekiwaliśmy. Funkcja, w której powstał obiekt lambda, może go na zakończenie zwrócić, ale zmienne lokalne funkcji nie mogą być w nim przechowane przez referencję. 258 Zmienne przechwycone implicite: [=] przechwycenie przez wartość wszystkich zmiennych lokalnych z otoczenia [&] przechwycenie przez referencję wszystkich zmiennych lokalnych z otoczenia [=, lista referencji] przechwycenie przez referencję zmiennych wymienionych w liście referencji, natomiast przez wartość wszystkich pozostałych zmiennych lokalnych z otoczenia [&, lista referencji] przechwycenie przez wartość zmiennych wymienionych w liście referencji, natomiast przez referencję wszystkich pozostałych zmiennych lokalnych z otoczenia Zmienne przechwycone implicite: sprawdzenie, czy długość jest większa od wartości przechowywanej w zmiennej sz: wc = find_if(words.begin(), words.end(), [=](const string &s) { return s.size() >= sz; ); Zmienne przechwycone implicite i explicite: Przykład na mieszane przechwytywanie implicite i explicite (domyślne i jawne): char c = ' '; for_each(words.begin(), words.end(), [=, &os](const string &s) { os << s << c; ); Dla mieszanego sposobu przechwytywania pierwszym elementem w liście przechwytywanych zmiennych musi być & lub =. Ten symbol ustala domyślny sposób przechwytywania, który będzie użyty wobec zmiennych niewymienionych po przecinku. Zmienne wymienione po przecinku musza być przechwytywane w sposób przeciwny do domyślnego. Modyfikacja przechwyconych zmiennych: Domyślnie w kodzie lambdy nie wolno jest modyfikować zmiennych przechwyconych przez wartość. Jeżeli potrzebna jest modyfikacja, stosujemy słowo kluczowe mutable size_t v1 = 42; // zmienna lokalna auto f3 = [v1] () mutable { return ++v1; v1 = 0; auto j = f3(); // j ==

15 Modyfikacja przechwyconych zmiennych: O tym, czy zmienna przechwycona sposobem przez referencje może być zmieniana, decyduje wyłącznie to, czy referencja dotyczy zmiennej typu const, czy nie. size_t v1 = 42; // zmienna lokalna, która nie jest const // 'v1' jest referencją na zmienną lokalną nie-const auto f2 = [&v1] { return ++v1; // modyfikuje 'v1' v1 = 0; auto j = f2(); // j == 1 Specyfikowanie typu zwracanych danych: Kiedy w kodzie wyrażenia lambda występuje tylko instrukcja return nie ma potrzeby specyfikowania typu zwracanych danych, np. : transform(vi.begin(), vi.end(), vi.begin(), [](int i) { return i < 0? -i : i; ); Kiedy w kodzie wyrażenia występuje jakiekolwiek inne wyrażenie niż return, domyślnie wyrażenie zwraca void. transform(vi.begin(), vi.end(), vi.begin(), [](int i) { if (i<0) return -i; else return i; ); Pojawia się problem, bo miała być zwrócona wartość absolutna, a nie ma nic Specyfikowanie typu zwracanych danych: Aby jawnie podać zwracany typ danych należy typ zwracanych danych zadeklarować w miejscu tuż za nagłówkiem z wykorzystaniem strzałki -> (tj. wg notacji trailing return type); transform(vi.begin(), vi.end(), vi.begin(), [](int i) -> int { if (i < 0) return -i; else return i; ); C++ 11: Tablice (kontenery) mieszające 265 Tablica mieszająca to uogólnienie zwykłej tablicy. Czynność wyszukiwania jest dużo szybsza niż w listach i kontenerach asocjacyjnych. W tablicy zwykłej element o kluczu k trafia na pozycję k (zbiór danych jest reprezentowany jako tablica, gdzie każdej pozycji odpowiada wartość klucza k z uniwersum kluczy. Wady: pola nie wykorzystane pozostają puste, k nie musi być indeksem ze zdefiniowaną arytmetyką) W tablicy mieszającej element o kluczu k jest przechowywany w pozycji h(k), gdzie h to funkcja kodująca (haszująca). Funkcja h odwzorowuje zbiór kluczy na zbiór pozycji w tablicy. Wady: też są.. (np. problem konfliktów), ale i tak jest szybciej. 267 Szybkość: Zamiast logarytmicznego czasu dostępu dla kontenerów przechowujących dane w postaci drzew binarnych stały czas dostępu, niezależnie od rozmiaru danych (brzmi słodko, do tego jest jednak jeszcze pewien tekst drobnym druczkiem, ale o tym jeszcze nie teraz) Zamiana wartości klucza na wartość indeksu tablicowego daje ten efekt. Przykład takiego postępowania: funkcje isalpha i isdigit, które sięgają do tablic indeksowanych 256 wartościami wszystkich możliwych znaków ASCII i sprawdzają wartość komórki reprezentującej flagę prawda/fałsz. To jest jednak niepraktyczne, kiedy dziedzina kluczy jest wielka, a zbiór wykorzystanych wartości niewspółmiernie mniejszy

16 Tablica mieszająca zarządza zbiorem kubełków, które są indeksowane liczbami całkowitymi. Wartość kluczowa k jest haszowana funkcją h, która zamienia ją na liczbę całkowitą z szerokiego zakresu wartości, a następnie wartość przypisana do tego klucza jest wkłada do kubełka wskazanego przez tę liczbę (w praktyce indeks jest obliczany jako wynik działania: h(k) modulo całkowita liczba kubełków). Każdy kubełek może zawierać więcej niż jeden element, które są przechowywane w postaci listy. Aby odczytać wartość dla zadanego klucza, obliczane jest h(k) i określany kubełek, w którym następnie odbywa się tradycyjne poszukiwanie żądanego elementu. Kiedy liczba danych w kontenerze będzie rosła, operacja haszowania oraz dostęp do kubełka pozostanie stały, ale czas szukania w kubełku będzie liniowy, a jego wartość będzie zależała od liczby elementów w kubełku. Aby utrzymać stały czas dostępu 1. liczba kubełków musi rosnąć wraz ze wzrostem liczby danych. 2. funkcja mieszająca powinna równomiernie rozkładać elementy po kubełkach. To oznacza, że o ile logarytmiczny czas dostępu w standardowych kontenerach jest gwarantowany, o tyle stały czas w kontenerach mieszających nie. A zły wybór funkcji mieszającej oraz mała liczba kubełków da w konsekwencji liniowy czas dostępu Dwa symptomy, że coś jest źle: Nierówno wypełnione kubełki oraz przepełnione kubełki. Lekarstwo: przemieszanie (rehashing) kontenera zwiększenie liczby kubełków i ponowna dystrybucja elementów. Kontenery mieszające: 1. unordered_set 2. unordered_multiset 3. unordered_map 4. unordered_multimap Ale to i tak nie pomoże na słabą funkcję mieszającą. W tym przypadku najlepszym wyjściem są testy obciążeniowe na dużych zbiorach wiarygodnych danych wykonane jeszcze przed oddaniem aplikacji do użytku Choć kontener jest unordered, to metody begin() i end() działają intuicyjnie zwracają pierwszy i ostatni element. Za to nie ma żadnej relacji porządkującej elementy pobrane przez odwołanie się do wartości sąsiedniej iteratora są podawane w kolejności takiej, jak to aktualnie wynika z funkcji mieszającej i kubełków raczej nie do odgadnięcia dla użytkownika. W razie spadku szybkości dostępu przemieszanie odbywa się automatycznie, ale można je też wymusić. Mamy też dostęp do podstawowych parametrów: liczba kubełków, liczba elementów w każdym kubełku oraz jakie są aktualne elementy w danym kubełku, aby samemu podjąć decyzję co do zmiany funkcji mieszającej czy też przemieszania. 273 unordered_set<int> uset; int int_value = 2;... uset.insert(int_value); // w razie potrzeby - przemiesza... unordered_set<int>::iterator it = uset.find(int_value); if(it!= uset.end()) cout << "found!" << endl; else cout << "not found!" << endl;... for(unordered_set<int>::iterator it = uset.begin(); it!= uset.end(); ++it) cout << *it << endl; // wartości w porządku nieznanym

17 typedef unordered_map<string, int> Umap_t; Umap_t umap; string string_var("dobromir"); int int_var = 5; umap[string_var] = int_var; umap.insert(umap_t::value_type("szpak", 4)); Umap_t::iterator itm = umap.find(string_var); if(itm!= umap.end()) cout << "klucz: " << itm->first << " ma: " << itm->second << endl; else cout << "brak!" << endl; for(umap_t::iterator itm = umap.begin(); itm!= umap.end(); ++itm) cout << "[" << itm->first << "," << itm->second << "] " << endl; Dostarczanie własnej metody porównania i mieszającej Przechowując w zbiorze mieszającym (unordered_set) dane naszego własnego typu, należy dostarczyć dwóch mechanizmów niezbędnych do poprawnego działania kontenera: 1. porównanie np. jako metoda zdefiniowana w naszej klasie. 2. mieszanie (w celu obliczenia indeksu dla zadanej wartości naszego typu) np. jako obiekt funkcyjny. Ich nagłówek jest dokładnie określony, tylko wewnętrzne działanie pozostaje w gestii autora kodu Dostarczanie własnej metody porównania i mieszającej Metoda porównująca: class MojTyp { // typ danych przechowywany w zbiorze public: bool operator== (const MojTyp& t) const { /* tutaj porównanie */ Funkcja mieszająca: struct Hash_MojTyp { // mieszający obiekt funkcyjny dla MojTyp std::size_t operator() (const MojTyp& t) const { /* tutaj obliczenie na podstawie wartości MojTyp */ Dostarczanie własnej metody porównania i mieszającej Jeżeli nie ma możliwości edytować plik z definicją klasy reprezentującej typ przechowywanych danych, to należy przygotować obiekt funkcyjny porównujący: struct Equal_MojTyp { // porównujacy obiekt funkcyjny dla MojTyp bool operator() (const MojTyp& t1, const MojTyp& t2) const { /* tutaj porównanie, zwraca 'true' tylko jeżeli (!(t1<t2) &&!(t1>t2)) */ Zbiór mieszający zdefiniowany do przechowywania naszego typu danych Te dwa mechanizmy należy zadeklarować jako kolejne dwa parametry szablonu reprezentującego kontener: unordered_set< MojTyp, Hash_MojTyp, Equal_MojTyp> zbior_mojtyp; Strojenie parametrów kontenera Aby ocenić efektywność kontenera, potrzebujemy znać kluczowe parametry pracy: cout << "Liczba elementów: " << umap.size() << endl; cout << "Liczba kubełków: " << umap.bucket_count() << endl; cout << "wsp. załadowania: " << umap.load_factor() << endl; cout << "max wsp. załadowania: " << umap.max_load_factor() << endl; Chyba, że porównanie jest metodą klasy MojTyp. Wtedy wystarczy tylko: unordered_set< MojTyp, Hash_MojTyp> zbior_mojtyp; Max wsp. załadowania poziom, który powoduje automatyczne uruchomienie procesu przemieszania

18 Strojenie parametrów kontenera Sprawdzenie zajętości kubełków: for(int i = 0; i < umap.bucket_count(); ++i) { cout << "kubełek " << i << " zawiera " << umap.bucket_size(i) << " elementów " << endl; Przejrzenie zawartości kubełków: for(int i = 0; i < umap.bucket_count(); ++i) { cout << "kubełek " << i << " zawiera: "; for(umap_t::local_iterator it = umap.begin(i); it!= umap.end(i); ++it) { cout << "[" << it->first << ", " << it->second << "] "; 281 Strojenie parametrów kontenera Sprawdzenie działania funkcji mieszającej: Umap_t::hasher hfunc = umap.hash_function(); // wskaźnik do funkcji for(umap_t::const_iterator it = umap.begin(); it!= umap.end(); ++it) { cout << it->first << " jest mieszane na " << hfunc(it->first) << endl; cout << endl; 282 Porównanie efektywności Źródło: Using TR1ʼs unordered_set and unordered_map, David Kieras, EECS Department, University of Michigan, October 18, 2008, white paper. Dokonano eksperymentalnego porównania szybkości działania programu: 1. posługującego się dwoma typami kontenerów: klasyczny set i pochodzący z TR1 unordered_set 2. dla dwóch typów danych przechowywanych w tych kontenerach: tanich i kosztownych obliczeniowo w porównywaniu. Razem cztery przypadki. Porównanie efektywności Tanie obliczeniowo typy danych: class Cheap { private: int i; public: Cheap(int i_ = -1) : i(i_) { typedef int key_type; key_type get_key() const {return i; bool operator< (const Cheap& rhs) const {return i < rhs.i; bool operator== (const Cheap& rhs) const {return i == rhs.i; friend ostream& operator<< (ostream& os, const Cheap& x); void print() const {cout << *this << endl; Porównanie efektywności Kosztowne obliczeniowo typy danych: class Expensive { private: string s; public: Expensive(int i = -1) { ostringstream oss; oss << "abcdefghijklmnopqrstuvwxyz" << i; s = oss.str(); //długie łańcuchy, różnią się na ostatnich polach typedef string key_type; const key_type& get_key() const {return s; bool operator< (const Expensive& rhs) const {return s < rhs.s; bool operator== (const Expensive& rhs) const {return s == rhs.s; friend ostream& operator<< (ostream& os, const Expensive& x); 285 Porównanie efektywności Funkcja mieszająca (szablon klasy bazowej funktora): template <typename T> struct MyHash { size_t operator()(const T&) const { assert(!"myhash unspecialized operator() has been called!"); return 0;

19 Porównanie efektywności Tania funkcja mieszająca (konkretyzacja szablonu) : template <> struct MyHash<Cheap> { size_t operator()(const Cheap& c) const { return static_cast<size_t>(c.get_key()); // just use the integer key value Porównanie efektywności Kosztowna funkcja mieszająca (konkretyzacja szablonu): template <> struct MyHash<Expensive> { size_t operator()(const Expensive& e) const { const string& s = e.get_key(); size_t result = 0; for (string::const_iterator i = s.begin(); i!= s.end(); ++i) result = (result * 131) + *i; return result; Parametry eksperymentu 1. Warianty zajętości kontenera: 10, 50, 100, 500, 1000, 5000, 10000, 50000, , , elementów. 2. Działanie: milion wywołań instrukcji szukającej dla każdego przypadku. 3. Pomiar: sumaryczny czas miliona wywołań (w sekundach) 4. Sprzęt: Mac Pro (quad Intel processor 2.66 GHz, 2 GB). 289 Czas dostępu do kontenera 290 STL: biblioteki alternatywne 1. SGI - Silicon Graphics International Corp., (początkowo Silicon Graphics Inc.) powstała na początku lat 80 (założyciele: Jim Clark, były profesor uniwersytetu Stanforda oraz grupa jego studentów): 2. Dinkumware założona w 1995 aby licencjonować biblioteki rozwijane przez P. J. Plaugera. Ostatnie osiągnięcia: pierwsza kompletna implementacja bibliotek wg założeń i wymagań standardu C++11 (dla Microsoft Visual Studio 11 Beta): Czas dostępu do kontenera skala logarytmiczna

20 STL: obliczenia matematyczne Wsparcie dla obliczeń matematycznych Jest wiele bibliotek: 1. Boost - sekcja Math and numerics: 2. Eigen 3. Armadillo Dziękuję

C++11: nullptr C++ 11: C++ 11: nullptr. Wyrażenia lambda. Zerowanie wskaźnika Do wyzerowania wskaźnika posługujemy się NULL bądź 0.

C++11: nullptr C++ 11: C++ 11: nullptr. Wyrażenia lambda. Zerowanie wskaźnika Do wyzerowania wskaźnika posługujemy się NULL bądź 0. C++11: nullptr Zerowanie wskaźnika Do wyzerowania wskaźnika posługujemy się NULL bądź 0. C++ 11: nullptr To są liczby. Stąd może pojawić się niejednoznaczność: void fun(int); // trzy przeciążenia fun void

Bardziej szczegółowo

C++11: metody usunięte i jawnie domyślne C++ 11: Metody usunięte i jawnie domyślne

C++11: metody usunięte i jawnie domyślne C++ 11: Metody usunięte i jawnie domyślne W C++11 kompilator generuje automatycznie dla przykładowej klasy Klasa: C++ 11: Metody usunięte i jawnie domyślne Konstruktor domyślny: Klasa() Konstruktor kopiujący: Klasa(const Klasa& k) Operator przypisania:

Bardziej szczegółowo

C++11: szablony zewnętrzne C++ 11: C++11: szablony zewnętrzne. C++11: szablony zewnętrzne. C++11: szablony zewnętrzne C++ 11: Szablony zewnętrzne

C++11: szablony zewnętrzne C++ 11: C++11: szablony zewnętrzne. C++11: szablony zewnętrzne. C++11: szablony zewnętrzne C++ 11: Szablony zewnętrzne C++11: szablony zewnętrzne Szablony zewnętrzne Zdarza się, że szablon np. funkcji jest wykorzystywany w wielu plikach kodu źródłowego. Dodatkowo przyjmijmy, że w każdym z plików będzie potrzebna konkretyzacja

Bardziej szczegółowo

C++ 11: C++ 11: C++11: jednolita inicjalizacja. C++11: jednolita inicjalizacja. C++11: jednolita inicjalizacja. C++11: initializer_list

C++ 11: C++ 11: C++11: jednolita inicjalizacja. C++11: jednolita inicjalizacja. C++11: jednolita inicjalizacja. C++11: initializer_list C++11: jednolita inicjalizacja Jednolita inicjalizacja za pomocą nawiasów klamrowych: Możliwa do zastosowania do dowolnej klasy, struktury czy unii, o ile istnieje (zdefiniowany jawnie lub implicite) konstruktor

Bardziej szczegółowo

C++11. C++ 11 wybrane elementy. C++11: referencje do rvalue C++ 11: C++11: referencje do rvalue. C++11: referencje do rvalue. Referencje do rvalue

C++11. C++ 11 wybrane elementy. C++11: referencje do rvalue C++ 11: C++11: referencje do rvalue. C++11: referencje do rvalue. Referencje do rvalue C++ 11 wybrane elementy C++11 Lista rozszerzeń C++11 obecnych w VC2013: 1. Referencje do rvalue, 2. Jednolite inicjowanie i delegowanie konstruktorów, 3. Konstruktory delegujące 4. Jednolita inicjalizacja

Bardziej szczegółowo

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi EGZAMIN PIERWSZY (25 CZERWCA 2013) JĘZYK C++ poprawiam ocenę pozytywną z egzaminu 0 (zakreśl poniżej x) 1. Wśród poniższych wskaż poprawną formę definicji

Bardziej szczegółowo

STL: kontenery C++: STL: kontenery. STL: kontenery. STL: kontenery. STL: kontenery. Fabryka obiektów. Fabryka obiektów. Fabryka obiektów przykład:

STL: kontenery C++: STL: kontenery. STL: kontenery. STL: kontenery. STL: kontenery. Fabryka obiektów. Fabryka obiektów. Fabryka obiektów przykład: Fabryka obiektów C++: Fabryka obiektów Klasa, której obiekty pośrednicza przy tworzeniu innych obiektów. Pomagają tworzyć obiekty, jeżeli informacja o typie odnosi się do konkretnego typu, znanego w momencie

Bardziej szczegółowo

C++11. C++ 11 wybrane elementy. C++11: referencje do rvalue C++ 11: C++11: referencje do rvalue. C++11: referencje do rvalue. Referencje do rvalue

C++11. C++ 11 wybrane elementy. C++11: referencje do rvalue C++ 11: C++11: referencje do rvalue. C++11: referencje do rvalue. Referencje do rvalue C++ 11 wybrane elementy C++11 Lista rozszerzeń C++11 obecnych w VC2013: 1. Referencje do rvalue, 2. Jednolite inicjowanie i delegowanie konstruktorów, 3. Konstruktory delegujące 4. Jednolita inicjalizacja

Bardziej szczegółowo

Podstawy programowania skrót z wykładów:

Podstawy programowania skrót z wykładów: Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace

Bardziej szczegółowo

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów Operatory są elementami języka C++. Istnieje zasada, że z elementami języka, takimi jak np. słowa kluczowe, nie można dokonywać żadnych zmian, przeciążeń, itp. PRZECIĄŻANIE OPERATORÓW Ale dla operatorów

Bardziej szczegółowo

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU Inicjalizacja agregatowa zmiennej tablicowej int a[5] = 1,2,3,4,5 INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU Struktury są również agregatami, dlatego: struct X double f; char c; X x1 = 1, 2.2, 'c' Ale

Bardziej szczegółowo

Programowanie obiektowe w C++ Wykład 12

Programowanie obiektowe w C++ Wykład 12 Programowanie obiektowe w C++ Wykład 12 dr Lidia Stępień Akademia im. Jana Długosza w Częstochowie L. Stępień (AJD) 1 / 22 Zakresowe pętle for double tab[5] {1.12,2.23,3.33,4.12,5.22 for(double x: tab)

Bardziej szczegółowo

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość 2. Poprawna definicja wskażnika b to: a) float *a, **b = &a; b) float

Bardziej szczegółowo

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje. Podstawowe elementy proceduralne w C++ Program i wyjście Zmienne i arytmetyka Wskaźniki i tablice Testy i pętle Funkcje Pierwszy program // Niezbędne zaklęcia przygotowawcze ;-) #include using

Bardziej szczegółowo

Szablony klas, zastosowanie szablonów w programach

Szablony klas, zastosowanie szablonów w programach Szablony klas, zastosowanie szablonów w programach 1. Szablony klas i funkcji 2. Szablon klasy obsługującej uniwersalną tablicę wskaźników 3. Zastosowanie metody zwracającej przez return referencję do

Bardziej szczegółowo

Zaawansowane programowanie w C++ (PCP)

Zaawansowane programowanie w C++ (PCP) Zaawansowane programowanie w C++ (PCP) Wykład 6 - szablony. dr inż. Robert Nowak - p. 1/15 Kolekcje i algorytmy» Deklaracja szablonu y Pojęcia niezależne od typu: kolekcje (np. listy) algorytmy (np. znajdowania

Bardziej szczegółowo

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { Przeciążanie operatorów [] Przykład: klasa reprezentująca typ tablicowy. Obiekt ma reprezentować tablicę, do której można się odwoływać intuicyjnie, np. Tab[i] Ma być też dostępnych kilka innych metod

Bardziej szczegółowo

Programowanie w C++ Wykład 6. Katarzyna Grzelak. 1 kwietnia K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43

Programowanie w C++ Wykład 6. Katarzyna Grzelak. 1 kwietnia K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43 Programowanie w C++ Wykład 6 Katarzyna Grzelak 1 kwietnia 2019 K.Grzelak (Wykład 6) Programowanie w C++ 1 / 43 Pojęcia z poprzednich wykładów Tablica to ciag obiektów tego samego typu, zajmujacy ciagły

Bardziej szczegółowo

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy : Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy : class nazwa_klasy prywatne dane i funkcje public: publiczne dane i funkcje lista_obiektów;

Bardziej szczegółowo

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU Inicjalizacja agregatowa zmiennej tablicowej int a[5] = 1,2,3,4,5 INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU Struktury są również agregatami, dlatego: struct X double f; char c; X x1 = 1, 2.2, 'c' Ale

Bardziej szczegółowo

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri);

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { zdefiniuje. Integer::operator=(ri); Przeciążanie operatorów [] Przykład: klasa reprezentująca typ tablicowy. Obiekt ma reprezentować tablicę, do której można się odwoływać intuicyjnie, np. Tab[i] Ma być też dostępnych kilka innych metod

Bardziej szczegółowo

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki Dariusz Brzeziński Politechnika Poznańska, Instytut Informatyki int getmax (int a, int b) { return (a > b? a : b); float getmax (float a, float b) { return (a > b? a : b); long getmax (long a, long b)

Bardziej szczegółowo

Wykład 4: Klasy i Metody

Wykład 4: Klasy i Metody Wykład 4: Klasy i Metody Klasa Podstawa języka. Każde pojęcie które chcemy opisać w języku musi być zawarte w definicji klasy. Klasa definiuje nowy typ danych, których wartościami są obiekty: klasa to

Bardziej szczegółowo

Programowanie i struktury danych

Programowanie i struktury danych Programowanie i struktury danych 1 / 30 STL Standard Template Library, STL (ang. = Standardowa Biblioteka Wzorców) biblioteka C++ zawierająca szablony (wzorce), które umożliwiają wielokrotne użycie. Główne

Bardziej szczegółowo

Język C++ wykład VIII

Język C++ wykład VIII Programowanie uzupełnienie notatek: dr Jerzy Białkowski 1 2 3 4 Obiektowość języka C++ ˆ Klasa (rozszerzenie struktury), obiekt instancją klasy, konstruktory i destruktory ˆ Enkapsulacja - kapsułkowanie,

Bardziej szczegółowo

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE WSKAŹNIKI KLASOWE Wskaźniki klasowe Każdy obiekt zajmuje fragment pamięci i wszystkie obiekty tego samego typu zajmują fragmenty pamięci tej samej długości początek miejsca w pamięci zajmowanego przez

Bardziej szczegółowo

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Wykład I. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej Wykład I - semestr II Kierunek Informatyka Wydział Matematyki Stosowanej Politechniki Śląskiej Gliwice, 2015 c Copyright 2015 Janusz Słupik Zaliczenie przedmiotu Do zaliczenia przedmiotu niezbędne jest

Bardziej szczegółowo

Języki i techniki programowania Ćwiczenia 2

Języki i techniki programowania Ćwiczenia 2 Języki i techniki programowania Ćwiczenia 2 Autor: Marcin Orchel Spis treści: Język C++... 5 Przekazywanie parametrów do funkcji... 5 Przekazywanie parametrów w Javie.... 5 Przekazywanie parametrów w c++...

Bardziej szczegółowo

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij.

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta 16.09.2006. Strona 1 z 26. Powrót. Full Screen. Zamknij. Programowanie Sobera Jolanta 16.09.2006 Strona 1 z 26 1 Wprowadzenie do programowania 4 2 Pierwsza aplikacja 5 3 Typy danych 6 4 Operatory 9 Strona 2 z 26 5 Instrukcje sterujące 12 6 Podprogramy 15 7 Tablice

Bardziej szczegółowo

Programowanie obiektowe i C++ dla matematyków

Programowanie obiektowe i C++ dla matematyków Programowanie obiektowe i C++ dla matematyków Bartosz Szreder szreder (at) mimuw... 22 XI 2011 Uwaga! Ponieważ już sobie powiedzieliśmy np. o wskaźnikach i referencjach, przez które nie chcemy przegrzebywać

Bardziej szczegółowo

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje Funkcje (podprogramy) Mianem funkcji określa się fragment kodu, który może być wykonywany wielokrotnie z różnych miejsc programu. Ogólny zapis: typ nazwa(argumenty) ciało funkcji typ określa typ danych

Bardziej szczegółowo

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016 Wykład 1 3 marca 2016 Słowa kluczowe języka Java abstract, break, case, catch, class, const, continue, default, do, else, enum, extends, final, finally, for, goto, if, implements, import, instanceof, interface,

Bardziej szczegółowo

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje

public: // interfejs private: // implementacja // składowe klasy protected: // póki nie będziemy dziedziczyć, // to pole nas nie interesuje Zbudujemy klasę Definicję klasy zapiszmy w pliku tstring.h #ifndef TSTRING_H #define TSTRING_H #include // w pliku nagłówkowym NIE // otwieramy przestrzeni std // interfejs private: // implementacja

Bardziej szczegółowo

STL: Lekcja 1&2. Filozofia STL

STL: Lekcja 1&2. Filozofia STL STL: Lekcja 1&2 Tematy: Filozofia STL Po co nam STL? Podstawowa zawartość STL Co warto znać zanim zaczniemy pracę z STL?: wskaźniki Praca na tekstach: klasa String Vector: nowy wymiar standardowych tablic.

Bardziej szczegółowo

Algorytmy i Struktury Danych. Anna Paszyńska

Algorytmy i Struktury Danych. Anna Paszyńska Algorytmy i Struktury Danych Anna Paszyńska Tablica dynamiczna szablon Array Zbiory Zbiory template class Container {public: virtual ~Container() { }; virtual int Count() const = 0;

Bardziej szczegółowo

Część 4 życie programu

Część 4 życie programu 1. Struktura programu c++ Ogólna struktura programu w C++ składa się z kilku części: część 1 część 2 część 3 część 4 #include int main(int argc, char *argv[]) /* instrukcje funkcji main */ Część

Bardziej szczegółowo

Programowanie w C++ Wykład 7. Katarzyna Grzelak. 23 kwietnia K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40

Programowanie w C++ Wykład 7. Katarzyna Grzelak. 23 kwietnia K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40 Programowanie w C++ Wykład 7 Katarzyna Grzelak 23 kwietnia 2018 K.Grzelak (Wykład 7) Programowanie w C++ 1 / 40 Standard Template Library (STL) K.Grzelak (Wykład 7) Programowanie w C++ 2 / 40 C++ Templates

Bardziej szczegółowo

4. Funkcje. Przykłady

4. Funkcje. Przykłady 4. Funkcje Przykłady 4.1. Napisz funkcję kwadrat, która przyjmuje jeden argument: długość boku kwadratu i zwraca pole jego powierzchni. Używając tej funkcji napisz program, który obliczy pole powierzchni

Bardziej szczegółowo

Wstęp do programowania

Wstęp do programowania wykład 10 Agata Półrola Wydział Matematyki i Informatyki UŁ semestr zimowy 2018/2019 Przesyłanie argumentów - cd Przesyłanie argumentów do funkcji - tablice wielowymiarowe Przekazywanie tablic wielowymiarowych

Bardziej szczegółowo

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne

2. Klasy cz. 2 - Konstruktor kopiujący. Pola tworzone statycznie i dynamicznie - Funkcje zaprzyjaźnione - Składowe statyczne Tematyka wykładów 1. Wprowadzenie. Klasy cz. 1 - Język C++. Programowanie obiektowe - Klasy i obiekty - Budowa i deklaracja klasy. Prawa dostępu - Pola i funkcje składowe - Konstruktor i destruktor - Tworzenie

Bardziej szczegółowo

Operatory na rzecz typu TString

Operatory na rzecz typu TString Operatory na rzecz typu TString Dopiszmy w definicji klasy operator[], dzięki któremu potraktujemy obiekt jak tablicę class TString { public: char& operator[]( size_t n ); const char& operator[]( size_t

Bardziej szczegółowo

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) {

Automatyczne tworzenie operatora = Integer2& operator=(const Integer& prawy) { Przeciążanie a dziedziczenie class Integer2: public Integer Operatory, z wyjątkiem operatora przypisania są automatycznie dziedziczone w klasach pochodnych. Integer2(int i): Integer(i) Automatyczne tworzenie

Bardziej szczegółowo

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Dariusz Wardowski dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21 Przydzielanie pamięci Poniżej przedstawiono w C++ dwie klasy obrazujące sposób rezerwacji pamięci. class Osoba char imie[30];

Bardziej szczegółowo

Paradygmaty programowania

Paradygmaty programowania Paradygmaty programowania Programowanie generyczne w C++ Dr inż. Andrzej Grosser Cz estochowa, 2016 2 Spis treści 1. Zadanie 3 5 1.1. Wprowadzenie.................................. 5 1.2. Obiekty funkcyjne................................

Bardziej szczegółowo

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016 Wykład 9 28 kwiecień 2016 Java Collections Framework (w C++ Standard Template Library) Kolekcja (kontener) Obiekt grupujacy/przechowuj acy jakieś elementy (obiekty lub wartości). Przykładami kolekcji sa

Bardziej szczegółowo

Szablony funkcji i szablony klas

Szablony funkcji i szablony klas Bogdan Kreczmer bogdan.kreczmer@pwr.wroc.pl Zakład Podstaw Cybernetyki i Robotyki Instytut Informatyki, Automatyki i Robotyki Politechnika Wrocławska Kurs: Copyright c 2011 Bogdan Kreczmer Niniejszy dokument

Bardziej szczegółowo

Lab 9 Podstawy Programowania

Lab 9 Podstawy Programowania Lab 9 Podstawy Programowania (Kaja.Gutowska@cs.put.poznan.pl) Wszystkie kody/fragmenty kodów dostępne w osobnym pliku.txt. Materiały pomocnicze: Wskaźnik to specjalny rodzaj zmiennej, w której zapisany

Bardziej szczegółowo

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne Przeciążenie funkcji polega na użyciu funkcji z tą samą nazwą, które mają różne listy argumentów(różne typy, różna ilość lub to i inne).

Bardziej szczegółowo

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static), Tworzenie obiektów Dostęp do obiektów jest realizowany przez referencje. Obiekty w języku Java są tworzone poprzez użycie słowa kluczowego new. String lan = new String( Lancuch ); Obszary pamięci w których

Bardziej szczegółowo

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p. Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni Wykład 3 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Abstrakcja funkcyjna Struktury Klasy hermetyzacja

Bardziej szczegółowo

Język C++ Różnice między C a C++

Język C++ Różnice między C a C++ Język C++ Różnice między C a C++ Plan wykładu C a C++ Różnice ogólne Typy Deklaracje zmiennych C++ jako rozszerzenie C Domyślne argumenty funkcji Przeciążanie funkcji Referencje Dynamiczny przydział pamięci

Bardziej szczegółowo

EGZAMIN 2 (14 WRZEŚNIA 2015) JĘZYK C++

EGZAMIN 2 (14 WRZEŚNIA 2015) JĘZYK C++ IMIĘ i NAZWISKO: przykładowe odpowiedzi NR: 0 EGZAMIN 2 (14 WRZEŚNIA 2015) JĘZYK C++ 1. Napisz precyzyjnie co to jest ptr jeśli: const * const Foo ptr; ptr to stały wskaźnik do stałego obiektu typu Foo

Bardziej szczegółowo

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja

Bardziej szczegółowo

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny: Wskaźniki nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny: typ nw; /* definicja zmiennej nw typu typ */ typ *w_nw; /* definicja

Bardziej szczegółowo

Zaawansowane programowanie w C++ (PCP)

Zaawansowane programowanie w C++ (PCP) Wykład 9 - powtórzenie. 11 maja 2007 Powtórzenie materiału obiekty automatyczne, statyczne, tymczasowe, dynamiczne dziedziczenie, agregacja polimorfizm, funkcje wirtualne wzorce projektowe (strukturalne,

Bardziej szczegółowo

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018 Informatyka I Klasy i obiekty. Podstawy programowania obiektowego dr inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2018 Plan wykładu Pojęcie klasy Deklaracja klasy Pola i metody klasy

Bardziej szczegółowo

I - Microsoft Visual Studio C++

I - Microsoft Visual Studio C++ I - Microsoft Visual Studio C++ 1. Nowy projekt z Menu wybieramy File -> New -> Projekt -> Win32 Console Application w okienku Name: podajemy nazwę projektu w polu Location: wybieramy miejsce zapisu i

Bardziej szczegółowo

Szablony. Szablony funkcji

Szablony. Szablony funkcji Szablony Szablony sa mechanizmem ponownego wykorzystania kodu (reuse) W przypadku funkcji ponownie wykorzystany jest algorytm W przypadku klas ponownie wykorzystane sa wszystkie skladowe Deklaracja szablonu

Bardziej szczegółowo

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006)

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006) Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006) Część 1. Teoria Wyjaśnij pojęcia, podaj przykład: klasa obiekt konstruktor destruktor kapsułkowanie (hermetyzacja) wskaźnik this

Bardziej szczegółowo

PARADYGMATY PROGRAMOWANIA Wykład 4

PARADYGMATY PROGRAMOWANIA Wykład 4 PARADYGMATY PROGRAMOWANIA Wykład 4 Metody wirtualne i polimorfizm Metoda wirualna - metoda używana w identyczny sposób w całej hierarchii klas. Wybór funkcji, którą należy wykonać po wywołaniu metody wirtualnej

Bardziej szczegółowo

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4 Dr inż. Dariusz JĘDRZEJCZYK Wskaźniki Dynamiczna alokacja pamięci Przykłady 11/3/2016 AGH, Katedra Informatyki Stosowanej i Modelowania 2 Wskaźnik to

Bardziej szczegółowo

Wykład 8: klasy cz. 4

Wykład 8: klasy cz. 4 Programowanie obiektowe Wykład 8: klasy cz. 4 Dynamiczne tworzenie obiektów klas Składniki statyczne klas Konstruktor i destruktory c.d. 1 dr Artur Bartoszewski - Programowanie obiektowe, sem. 1I- WYKŁAD

Bardziej szczegółowo

TEMAT : KLASY DZIEDZICZENIE

TEMAT : KLASY DZIEDZICZENIE TEMAT : KLASY DZIEDZICZENIE Wprowadzenie do dziedziczenia w języku C++ Język C++ możliwa tworzenie nowej klasy (nazywanej klasą pochodną) w oparciu o pewną wcześniej zdefiniowaną klasę (nazywaną klasą

Bardziej szczegółowo

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 5. Karol Tarnowski A-1 p. Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni Wykład 5 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Przestrzenie nazw Standardowa biblioteka szablonów

Bardziej szczegółowo

Przeciążenie operatorów

Przeciążenie operatorów Przeciążenie operatorów W C++ można przeciążyć większość operatory tak, żeby wykonywali zadania, charakterystyczne dla danej klasy Po przeciążeniu odpowiednich operatorów można posługiwać się obiektami

Bardziej szczegółowo

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec PROE wykład 2 operacje na wskaźnikach dr inż. Jacek Naruniec Zmienne automatyczne i dynamiczne Zmienne automatyczne: dotyczą kontekstu, po jego opuszczeniu są usuwane, łatwiejsze w zarządzaniu od zmiennych

Bardziej szczegółowo

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np

Klasa jest nowym typem danych zdefiniowanym przez użytkownika. Najprostsza klasa jest po prostu strukturą, np Klasy Klasa jest nowym typem danych zdefiniowanym przez użytkownika Wartości takiego typu nazywamy obiektami Najprostsza klasa jest po prostu strukturą, np struct Zespolona { Klasy jako struktury z operacjami

Bardziej szczegółowo

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6 JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM Wykład 6 1 SPECYFIKATOR static Specyfikator static: Specyfikator ten powoduje, że zmienna lokalna definiowana w obrębie danej funkcji nie jest niszczona

Bardziej szczegółowo

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r. M. Trzebiński C++ 1/14 Podstawy języka C++ Maciej Trzebiński Instytut Fizyki Jądrowej Polskiej Akademii Nauk Praktyki studenckie na LHC IVedycja,2016r. IFJ PAN Przygotowanie środowiska pracy Niniejsza

Bardziej szczegółowo

Mechanizm dziedziczenia

Mechanizm dziedziczenia Mechanizm dziedziczenia Programowanie obiektowe jako realizacja koncepcji ponownego wykorzystania kodu Jak przebiega proces dziedziczenia? Weryfikacja formalna poprawności dziedziczenia Realizacja dziedziczenia

Bardziej szczegółowo

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami 1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami Celem tych zajęć jest zrozumienie i oswojenie z technikami programowania przy pomocy wskaźników w języku C++. Proszę przeczytać rozdział 8.

Bardziej szczegółowo

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej. Polimorfizm jest filarem programowania obiektowego, nie tylko jeżeli chodzi o język C++. Daje on programiście dużą elastyczność podczas pisania programu. Polimorfizm jest ściśle związany z metodami wirtualnymi.

Bardziej szczegółowo

Programowanie i struktury danych. Wykład 4 Dr Piotr Cybula

Programowanie i struktury danych. Wykład 4 Dr Piotr Cybula Programowanie i struktury danych Wykład 4 Dr Piotr ybula Typ wska ź nikowy int* pointer; //wskaźnik do zmiennych typu int pozwala na dostęp do dowolnego miejsca pamięci (zmienne

Bardziej szczegółowo

Podstawy Programowania C++

Podstawy Programowania C++ Wykład 3 - podstawowe konstrukcje Instytut Automatyki i Robotyki Warszawa, 2014 Wstęp Plan wykładu Struktura programu, instrukcja przypisania, podstawowe typy danych, zapis i odczyt danych, wyrażenia:

Bardziej szczegółowo

C++ wprowadzanie zmiennych

C++ wprowadzanie zmiennych C++ wprowadzanie zmiennych Każda zmienna musi być zadeklarowana, należy określić jej nazwę (identyfikator) oraz typ. Opis_typu lista zmiennych Dla każdej zmiennej rezerwowany jest fragment pamięci o określonym

Bardziej szczegółowo

Programowanie Komponentowe Zarządzanie obiektami: kontenery

Programowanie Komponentowe Zarządzanie obiektami: kontenery Programowanie Komponentowe Zarządzanie obiektami: kontenery dr inż. Ireneusz Szcześniak jesień 2016 roku Kontenery Kontener w C++ to generyczna struktura danych. Przechowuje elementy jednego dowolnego

Bardziej szczegółowo

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this Wstęp do programowania obiektowego WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this 1 Nazwa typu Rozmiar Zakres Uwagi bool 1 bit wartości true albo false stdbool.h TYPY ZNAKOWE

Bardziej szczegółowo

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy:

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy: Kurs C++ częśd II Podstawowa obsługa konsoli + zmienne. Autor: Dawid Chróścielski. Wprowadzanie i wyprowadzanie danych z/do konsoli. Jak wyprowadzad dane dowiedzieliśmy się już wcześniej (metoda cout z

Bardziej szczegółowo

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30 Programowanie w C++ Wykład 11 Katarzyna Grzelak 13 maja 2019 K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30 Klasy cd K.Grzelak (Wykład 11) Programowanie w C++ 2 / 30 Klasy - powtórzenie Klasy typy definiowane

Bardziej szczegółowo

Wprowadzenie do szablonów szablony funkcji

Wprowadzenie do szablonów szablony funkcji 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.

Bardziej szczegółowo

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27 Programowanie w C++ Wykład 12 Katarzyna Grzelak 28 maja 2018 K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27 Klasy cd K.Grzelak (Wykład 12) Programowanie w C++ 2 / 27 Klasy - powtórzenie Klasy typy definiowane

Bardziej szczegółowo

Obsługa wyjątków. Język C++ WW12

Obsługa wyjątków. Język C++ WW12 Obsługa wyjątków Pozwala zarządzać błędami wykonania w uporządkowany sposób. Umożliwia automatyczne wywołanie części kodu, funkcji, metod klas, który trzeba wykonać przy powstaniu błędów. try //blok try

Bardziej szczegółowo

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 7 maja K.Grzelak (Wykład 8) Programowanie w C++ 1 / 31

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 7 maja K.Grzelak (Wykład 8) Programowanie w C++ 1 / 31 Programowanie w C++ Wykład 8 Katarzyna Grzelak 7 maja 2018 K.Grzelak (Wykład 8) Programowanie w C++ 1 / 31 STL - powtórzenie STL Standard Template Libarary standardowa biblioteka szablonów Składowe biblioteki:

Bardziej szczegółowo

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład 6 Wskaźniki Krzysztof Banaś Podstawy programowania 1 Adresy zmiennych Język C pozwala na operowanie adresami w pamięci stąd, między innymi, kwalifikowanie C jako języka relatywnie

Bardziej szczegółowo

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie? 1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie? a) konstruktor b) referencje c) destruktor d) typy 2. Które z poniższych wyrażeń są poprawne dla klasy o nazwie

Bardziej szczegółowo

Programowanie w C++ Wykład 6. Katarzyna Grzelak. kwiecień K.Grzelak (Wykład 6) Programowanie w C++ 1 / 40

Programowanie w C++ Wykład 6. Katarzyna Grzelak. kwiecień K.Grzelak (Wykład 6) Programowanie w C++ 1 / 40 Programowanie w C++ Wykład 6 Katarzyna Grzelak kwiecień 2019 K.Grzelak (Wykład 6) Programowanie w C++ 1 / 40 STL - powtórzenie STL Standard Template Libarary standardowa biblioteka szablonów Składowe biblioteki:

Bardziej szczegółowo

Wprowadzenie do szablonów szablony funkcji

Wprowadzenie do szablonów szablony funkcji Wprowadzenie do szablonów szablony funkcji 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

Bardziej szczegółowo

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost; Klasy w C++ są bardzo ważnym narzędziem w rękach programisty. Klasy są fundamentem programowania obiektowego. Z pomocą klas będziesz mógł tworzyć lepszy kod, a co najważniejsze będzie on bardzo dobrze

Bardziej szczegółowo

6 Niektóre nowe cechy standardu C++11

6 Niektóre nowe cechy standardu C++11 6 Niektóre nowe cechy standardu C++11 Na podstawie: Nicolai M. Josuttis: The C++ Standard Library A Tutorial and Reference, Second Edition, Addison-Wesley 6.1 nullptr Dotychczas używano 0 lub NULL do wskazania,

Bardziej szczegółowo

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec PROE wykład 3 klasa string, przeciążanie funkcji, operatory dr inż. Jacek Naruniec Przypomnienie z ostatnich wykładów Konstruktory/destruktory i kolejność ich wywołania w złożonej klasie. Referencja Obiekty

Bardziej szczegółowo

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Operator przypisania. Jest czym innym niż konstruktor kopiujący! Operator przypisania Jest czym innym niż konstruktor kopiujący! Domyślnie jest zdefiniowany jako przypisanie składowa po składowej (zatem niekoniecznie bajt po bajcie). Dla klasy X definiuje się jako X&

Bardziej szczegółowo

ZASADY PROGRAMOWANIA KOMPUTERÓW

ZASADY PROGRAMOWANIA KOMPUTERÓW POLITECHNIKA WARSZAWSKA Instytut Automatyki i i Robotyki ZASADY PROGRAMOWANIA KOMPUTERÓW Język Język programowania: C/C++ Środowisko programistyczne: C++Builder 6 Wykład 9.. Wskaźniki i i zmienne dynamiczne.

Bardziej szczegółowo

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1 Tablice i struktury czyli złożone typy danych. Programowanie Proceduralne 1 Tablica przechowuje elementy tego samego typu struktura jednorodna, homogeniczna Elementy identyfikowane liczbami (indeksem).

Bardziej szczegółowo

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 16 kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27 Programowanie w C++ Wykład 5 Katarzyna Grzelak 16 kwietnia 2018 K.Grzelak (Wykład 1) Programowanie w C++ 1 / 27 Pojęcia z poprzednich wykładów Tablica to ciag obiektów tego samego typu, zajmujacy ciagły

Bardziej szczegółowo

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych. Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych. 1. Rodzaje pamięci używanej w programach Pamięć komputera, dostępna dla programu,

Bardziej szczegółowo

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce. 1 Podstawy c++ w pigułce. 1.1 Struktura dokumentu. Kod programu c++ jest zwykłym tekstem napisanym w dowolnym edytorze. Plikowi takiemu nadaje się zwykle rozszerzenie.cpp i kompiluje za pomocą kompilatora,

Bardziej szczegółowo

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 5. Karol Tarnowski A-1 p. Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni Wykład 5 Karol Tarnowski karol.tarnowski@pwr.edu.pl A-1 p. 411B Plan prezentacji Standardowa biblioteka szablonów (Standard Template

Bardziej szczegółowo

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40 Programowanie w C++ Wykład 5 Katarzyna Grzelak 26 marca 2018 9 kwietnia 2018 K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40 Pojęcia z poprzedniego wykładu Podział programu na funkcje podział na niezależne

Bardziej szczegółowo

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy KONSTRUKTORY

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy KONSTRUKTORY Inicjalizacja obiektu KONSTRUKTORY Inicjalizacja Przyczyną wielu błędów w programach jest nieprawidłowe zainicjalizowanie zmiennych na początku działania programu. Obiekt zawiera z reguły szereg pól ich

Bardziej szczegółowo

C-struktury wykład. Dorota Pylak

C-struktury wykład. Dorota Pylak C-struktury wykład Dorota Pylak C-struktury W języku C++, jak w każdym języku obiektowym, mamy możliwość definiowania własnych typów danych, wraz z określeniem operacji, jakie na tych danych można wykonywać.

Bardziej szczegółowo