Dzisiejszy wykład. Wzorce funkcji Wzorce klas Tablica asocjacyjna Składowe statyczne

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

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

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

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

Wzorce funkcji (szablony)

Operatory na rzecz typu TString

Jzyk C++ cz 3. Jarosław Gramacki Instytut Informatyki i Elektroniki ( $)*)+' *, - ( ' )*'.' '',*/ *, ','*0) 1 / ) %*+ 2'' 2" ( $%%) )'20 )*0) 1 / )

Szablony klas, zastosowanie szablonów w programach

Programowanie obiektowe w C++ Wykład 12

Język C++ wykład VIII

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

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

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

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

Dzisiejszy wykład. Klasa string. wersja prosta wersja ze zliczaniem odwołań. Wyjątki Specyfikator volatile Semafory

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

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

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

Wstęp do Programowania 2

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

Zaawansowane programowanie w C++ (PCP)

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

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

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

STL: Lekcja 1&2. Filozofia STL

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

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

Język C++ wykład VI. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VI. dr Jarosław Mederski.

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

Projektowanie klas c.d. Projektowanie klas przykład

Szablony funkcji i klas (templates)

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

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

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

PARADYGMATY PROGRAMOWANIA Wykład 4

PARADYGMATY PROGRAMOWANIA Wykład 3

Programowanie i struktury danych

C++ Przeładowanie operatorów i wzorce w klasach

Język C++ wykład VII. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VII. dr Jarosław Mederski. Spis.

Programowanie w języku C++

FUNKCJE WZORCOWE. Wykład 10. Programowanie Obiektowe (język C++) Funkcje wzorcowe wprowadzenie (2) Funkcje wzorcowe wprowadzenie (1)

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

Programowanie Obiektowo Zorientowane w języku C++ Klasy, pola, metody

Wyjątki (exceptions)

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Programowanie obiektowe i C++ dla matematyków

Szablon klasy std::vector

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

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

wykład V uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C++ klasy i obiekty wykład V dr Jarosław Mederski Spis Język C++ - klasy

Języki programowania - podstawy

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

KLASA UCZEN Uczen imię, nazwisko, średnia konstruktor konstruktor Ustaw Wyswietl Lepszy Promowany

Programowanie obiektowe

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

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

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

Programowanie obiektowe i C++ dla matematyków

Aby uzyskać zaliczenie w pierwszym terminie (do 30 stycznia 2018) rozliczyć trzeba co najmniej 8 projektów, po 4 z każdej z części: C++ oraz Python.

TEMAT : KLASY DZIEDZICZENIE

Zaawansowane programowanie w C++ (PCP)

Programowanie i struktury danych

Wskaźniki Cztery atrybuty zmiennej. Wskaźnik jest typem wartości. Operator * oznacza: Operator & oznacza: nazwa typ. wartość lokacja (adres)

Programowanie, część I

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

Programowanie komputerowe. Zajęcia 5

EGZAMIN PROGRAMOWANIE II (10 czerwca 2010) pytania i odpowiedzi

Wstęp do Programowania 2

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

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

Programowanie Obiektowew języku C++ Zadania L4

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

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Plik klasy. h deklaracje klas

Wstęp do programowania

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

Programowanie obiektowe, wykład nr 6. Klasy i obiekty

Programowanie w języku C++

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

Przekazywanie argumentów wskaźniki

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

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

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

Programowanie Procedurale

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

Szablony funkcji i szablony klas

Programowanie Komputerów

Programowanie 2. Język C++. Wykład 3.

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

Wykład 8: klasy cz. 4

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

Wstęp do Programowania 2

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

TEMAT : KLASY POLIMORFIZM

W przypadku STL w specyfikacji nazwy pliku nagłówkowego brak rozszerzenia tj. <string> <string.h> zamiast

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

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

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Dziedziczenie & W slajdach są materiały zapożyczone z

Transkrypt:

Dzisiejszy wykład Wzorce funkcji Wzorce klas Tablica asocjacyjna Składowe statyczne 1

Wzorce Często pojawia się konieczność pisania podobnych funkcji lub klas operujących na argumentach różnych typów int minimum(int x, int y) if (x < y) return x; else return y; double minimum(double x, double y) if (x < y) return x; else return y; Wzorce umożliwiają jednokrotne napisanie kodu, który będzie wykorzystywany dla wielu typów danych TYPE minimum(type x, TYPE y) if (x < y) else return x; return y; 2

Wzorce Słowo kluczowe Nazwa parametru określającego typ template <class atype> atype minimum(atype x, atype y) if(x<y) else return x; return y; Nazwa wzorca funkcji Wyraz atype jest nazwą podaną przez użytkownika, nie słowem kluczowym atype może być prawie dowolnym typem Operacja < musi być zdefiniowana dla atype 3

Wzorce #include <iostream> #include <string> using namespace std; template < class T > T minimum (T x, T y) if (x < y) return x; Definicja wzorca funkcji else return y; int main () Konkretyzacja wzorca dla danego typu/typów argumentów int x = 50, y = 30; string a = "hello", b = "goodbye"; cout << "minimum for ints " << minimum (x, y) << endl; cout << "minimum for strings " << minimum (a, b) << endl; 4

Wzorce Składnia deklaracji wzorca: Wzorzec klasy template <class atype> classname ; Wzorzec funkcji template <class atype> ReturnType functionname(arguments) // class definition // function definition 5

Funkcja zamieniająca obiekty #include <iostream> #include <string> using namespace std; template<class T> void swap_value(t& var1, T& var2) T temp; temp = var1; var1 = var2; var2 = temp; Działa dla wszystkich klas, dla których istnieje operator = int main() int int1 = 1, int2 = 2; cout << "original " << int1 << " " << int2 << endl; swap_value(int1, int2); cout << "after " << int1 << " " << int2 << endl; string s1 = "one", s2 = "two"; cout << "original " << s1 << " " << s2 << endl; swap_value(s1, s2); cout << "after " << s1 << " " << s2 << endl; 6

Funkcja zamieniająca obiekty // using swap_value template as before class Value private: int x; public: Value(int i = 0) : x(i) friend ostream& operator<<(ostream& out, Value v); ; ostream& operator<<(ostream& out, Value v) out << "value(" << v.x << ")"; return out; int main() Value v1(5), v2(10); cout << "original " << v1 << " " << v2 << endl; swap_value(v1, v2); cout << "after " << v1 << " " << v2 << endl; 7

Sortowanie bąbelkowe // using swap_value template as before template < class T > void bubblesort (T * A, unsigned int size) for (unsigned int i = 0; i < size-1; i++) for (unsigned int j = size - 1; j > i; j--) if (A[j] < A[j-1]) swap_value (A[j], A[j-1]); int main () string S[5]="ula","ala","ola","genowefa","stefania"; int bubblesort(s,5); bubblesort(i,3); for(int i=0;i<5;i++) cout<<s[i]<<endl; for(int i=0;i<3;i++) cout<<i[i]<<endl; I[3]=4,1234,-7; Działa dla wszystkich klas, dla których istnieje operator < i operator = 8

Wzorce z punktu widzenia kompilatora Podczas konkretyzacji wzorca kompilator wykonuje podobne czynności jak przy rozwijaniu makrodefinicji Programista pisze: minimum(2,3) Kompilator emituje kod dla nowej kopii funkcji nazywając ją np. minimum_int i zastępuje T przez int w całym kodzie wzorca Kompilator musi mieć dostęp do pełnego kodu wzorca w momencie konkretyzacji Zazwyczaj cały kod wzorca umieszczany jest w pliku nagłówkowym 9

Wzorzec klasy vector Parametr wzorca template<class C> class vector Nazwa wzorca C *dane; Słowa kluczowe unsigned int size; public: class index_out_of_range; explicit vector (int s); ~vector (); C& operator[] (unsigned int pos); C operator[] (unsigned int pos) const; vector (const vector<c> & s); void swap(vector<c>& s); vector<c> & operator= (const vector<c> & s); friend ostream & operator<< (ostream & o, const vector<c> & v); ; 10

Użycie parametru wzorca Do czego można użyć parametru wzorca: Do określenia typu danych używanego w klasie C *dane; Do określenia typu parametru metody void swap(vector<c>& s); Do określenia typu danej zwracanej przez metodę C& operator[] (unsigned int pos); 11

Konkretyzacja wzorca Dana jest deklaracja wzorca template<class C> class vector...; vector jest wzorcem klasy, aby uzyskać nazwę klasy należy dokonać konkretyzacji wzorca vector - nazwa wzorca klasy vector<int> - nazwa klasy, wektora liczb całkowitych Obiekty tworzy się przy użyciu skonkretyzowanego wzorca klasy vector<string> a(10); typedef vector<int> intvector; intvector b(5); Konkretny typ (string lub int) zostaje podstawiony pod formalny parametr wzorca (C) w definicji wzorca 12

Użycie wzorców klas Po konkretyzacji wzorca używa się tak samo jak zwykłej klasy vector<string> a(5), b(10); a.swap(b); Parametr dla funkcji zamiany został podany jako vector<c>& w definicji wzorca Został odwzorowany jako vector<string>& przy deklaracji obiektu a Stąd, przy wywołaniu swap musimy jako argument podać vector<string> 13

Implementacja metod wzorca klas template i parametry formalne template<class C> vector<c>::vector (int s) operator zasięgu i nazwa funkcji //member function body goes here ; nazwa klasy i parametry formalne template<class C> void vector<c>::swap(vector<c>& s) //member function body goes here ; typ wartości zwracanej template<class C> class vector Definicja od razu w //... deklaracji wygląda void swap(vector<c>& s) prościej //member function body goes here //... ; 14

Inicjalizacja pamięci i konstruktor domyślny Poniżej przedstawiono reguły określające inicjalizację pamięci zaalokowanej dynamicznie int reprezentuje tutaj dowolny typ POD (Plain Old Data), czyli taki, którego definicja wyglądałaby dokładnie tak samo w C class Object /*... */; Object* p1 = new Object; /* Object::Object() used */ Object* p2 = new Object(); /* Object::Object() used */ int* p3 = new int; /* not initialized! */ int* p4 = new int(); /* initialized to zero */ Object* p5 = new Object[7];/* Object::Object() used 7 times */ int* p6 = new int[7]; /* not initialized! */ Dlatego domyślny konstruktor wzoraca wektora jest nieco nadmiarowy explicit vector (int s) data = new C[s]; size = s; for (unsigned i = 0; i < size; i++) data[i] = C(); //redundant except POD types 15

Konstruktor kopiujący i wyjątki W przypadku wystąpienia wyjątku w konstruktorze klasy vector<c>, destruktor klasy vector<c> nie zostanie wywołany Dlatego należy zadbać o zwolnienie pamięci w przypadku wystąpienia wyjątku w konstruktorze template<class C> class vector //... vector (const vector<c> & s) dane = new C[s.size]; size = s.size; try for (unsigned i = 0; i < size; i++) dane[i] = s.dane[i]; catch(...) delete [] dane; throw; ; 16

Operator przypisania i wyjątki W celu zagwarantowania poprawnego działania operatora przypisania w przypadku zgłoszenia wyjątku przez operator przypisania dla typu C, operator przypisania implementujemy przy pomocy konstruktora kopiującego i funkcji swap template<class C> class vector //... void swap(vector<c>& s) C* t1=s.dane; unsigned int t2=s.size; s.dane=dane; s.size=size; dane=t1; size=t2; vector<c> & operator= (const vector<c> & s) if (this == &s) ; return *this; vector<c> n(s); swap(n); return *this; Funkcja swap nigdy nie zgłasza wyjątku W przypadku zgłoszenia wyjątku przez konstruktor kopiujący, obiekt pozostaje w niezmienionym stanie 17

Założenia co do parametru C wzorca vector Posiada konstruktor bezparametrowy użyty w konstruktorach do stworzenia tablicy obiektów typu C Posiada konstruktor kopiujący użyty przy przekazywaniu parametru w operatorze indeksowania Posiada operator przypisania użyty w operatorze przypisania wzorca vector<c> Posiada operator << użyty w operatorze << wzorca vector<c> 18

Wzorce klas z punktu widzenia kompilatora Programista pisze: vector<int> a; Kompilator emituje nową kopię klasy nazywając ją np. vector_int i zastępuje C przez int w całym kodzie wzorca klasy Kompilator musi mieć dostęp do pełnego kodu wzorca w momencie konkretyzacji Zazwyczaj cały kod wzorca umieszczany jest w pliku nagłówkowym 19

Wzorce klas i kontrola typów Ciała metod używają tych samych algorytmów dla wektora liczb całkowitych, liczb rzeczywistych czy łańcuchów tekstowych Kompilator wykonuje jednak kontrolę typów Jeżeli napiszemy vector<int> a; vector<double> b; vector<string> c; kompilator wygeneruje trzy różne klasy z normalnymi regułami kontroli typów a[7]="ala"; //compile-time error 20

Tablica asocjacyjna Tablica asocjacyjna to struktura danych, zawierająca zbiór par <klucz,wartość> Może być interpretowana jako funkcja przypisująca kluczowi odpowiednią wartość Może to być na przykład tablica liczb całkowitych indeksowana łańcuchami tekstowymi assoctab at; at["ala"]=15; at["ola"]=32; cout << at["ala"]<<at["ola"]<<at["ula"]<<endl; 21

Tablica asocjacyjna Tablicę asocjacyjną można zbudować w oparciu o strukturę listy class assoctab private: struct node node *next; char* key; int val; ; node * head; l head void insert (const char *key, int value); void clear (); node *find (const char *key) const; void swap (assoctab & l); public: assoctab (); assoctab (const assoctab & l); assoctab & operator= (const assoctab & l); ~assoctab (); int &operator[] (const char *); ; next=0x1234 key="ala" val=15 next=0x1334 key="ola" val=32 next=null key="ula" val=0 22

Tablica asocjacyjna - funkcja swap W celu zapewnienia właściwego działania operatora przypisania, zaimplementowano go przy pomocy konstruktora kopiującego i funkcji swap l1 head next=0x1234 key="ala" val=15 next=0x1334 key="ola" val=32 next=null key="ula" val=0 assoctab & assoctab::operator= (const assoctab & l) if (&l == this) return *this; assoctab t (l); swap (t); return *this; l2 head next=0x2234 key="tom" val=45 next=0x3334 key="ben" val=13 next=null key="jerry" val=7 23

Tablica asocjacyjna - funkcja swap Funkcja swap zamienia jedynie wskaźniki, nie może więc spowodować wyjątku l1 head next=0x1234 key="ala" val=15 next=0x1334 key="ola" val=32 next=null key="ula" val=0 l2 head next=0x2234 key="tom" val=45 next=0x3334 key="ben" val=13 next=null key="jerry" val=7 24

Tablica asocjacyjna - ulepszenie Czas wyszukiwania w tablicy asocjacyjnej zaimplementowanej jako lista jest proporcjonalny do liczby elementów w tablicy Często stosowaną metodą skrócenia czasu wyszukiwania jest zastosowanie funkcji mieszającej Funkcja mieszająca jest to funkcja, która dla każdego łańcucha tekstowego zwraca liczbę z przedziału <0...N-1>. Rozkład wartości powinien być równomierny dla wszystkich łańcuchów umieszczanych na liście Dobór odpowiedniej funkcji mieszającej dla danej dziedziny zastosowań jest sztuką unsigned int hash(const char*); 25

Tablica asocjacyjna z funkcją mieszającą Zamiast jednej listy, tworzymy N list Na każdej liście znajdują się węzły o tej samej wartości funkcji mieszającej dla klucza 0 1 2 3 4... N-1 W idealnym przypadku, długości wszystkich list są jednakowe i czas wyszukiwania skrócony n-krotnie 26

Tablica asocjacyjna z funkcją mieszającą W definicji klasy skorzystamy z uprzednio zdefiniowanego wzorca klasy vector class hashassoctab vector<assoctab> v; int chains; public: hashassoctab(unsigned int c): v(c),chains(c); unsigned int hash(const char* s) unsigned sum=0; while(*s) sum+=(unsigned char)(*s); s++; return sum % chains; int& operator[] (const char *s) return (v[hash(s)])[s]; // default constructor, destructor and assignment operator not necessary ; 27

Składowe statyczne Składowe statyczne są wspólne dla wszystkich obiektów danej klasy Metody statyczne nie otrzymują wskaźnika this Metody statyczne mogą korzystać jedynie ze składowych statycznych danej klasy Do składowych statycznych można odwoływać się zarówno za pośrednictwem jakiegoś obiektu (przy pomocy kropki), jak i przez nazwę klasy (operator wyboru zasięgu ::) Pola statyczne muszą być dokładnie raz zdefiniowane w programie (nie tylko zadeklarowane) #include <iostream> using namespace std; class example static int a; int v; public: static int getstatic() return a;; static void setstatic(int p) a=p;; example(int p): v(p); int fun()return v+a;; ; int example::a=42; int main() example e(27); example f(47); cout << example::getstatic()<<endl; f.setstatic(34); cout << e.fun()<<endl; ; 28