Wzorce (szablony) template<class T> {definicja wzorca} lub template<class TypElementu> lub template<class TypElementu1, class TypElementu2>

Podobne dokumenty
Programowanie i struktury danych

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

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

Szablony funkcji i klas (templates)

Szablony klas, zastosowanie szablonów w programach

Wykład 5 Wybrane zagadnienia programowania w C++ (c.d.)

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

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

Szablony funkcji i szablony klas

Sposoby przekazywania parametrów w metodach.

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

Stos liczb całkowitych

STL: Lekcja 1&2. Filozofia STL

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

Temat: Liniowe uporzdkowane struktury danych: stos, kolejka. Specyfikacja, przykładowe implementacje i zastosowania. Struktura słownika.

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

Wzorce funkcji (szablony)

Dla każdej operacji łącznie tworzenia danych i zapisu ich do pliku przeprowadzić pomiar czasu wykonania polecenia. Wyniki przedstawić w tabelce.

Algorytmy i Struktury Danych. Anna Paszyńska

Zaawansowane programowanie w C++ (PCP)

Projektowanie klas c.d. Projektowanie klas przykład

Wprowadzenie do szablonów szablony funkcji

Szablony. Szablony funkcji

Paradygmaty programowania

Wprowadzenie do szablonów szablony funkcji

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

Wstęp do wiadomości teoretycznych (nie, nie jest to masło maślane ani wstęp, wstępów proszę cierpliwie czytać)

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

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

1. Klasa typu sealed. Przykład 1. sealed class Standard{ class NowyStandard:Standard{ // błd!!!

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

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 8. Katarzyna Grzelak. 7 maja K.Grzelak (Wykład 8) Programowanie w C++ 1 / 31

Abstrakcyjny typ danych

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 VIII

Klasy generyczne. ZbiórLiczb. ZbiórCzegokolwiek. Zbiór

PARADYGMATY PROGRAMOWANIA Wykład 4

PARADYGMATY PROGRAMOWANIA Wykład 3

Kurs programowania. Wykład 9. Wojciech Macyna

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

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

Wstęp do programowania

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

Zaawansowane programowanie w języku C++ Funkcje uogólnione - wzorce

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

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

DYNAMICZNE PRZYDZIELANIE PAMIECI

Wyjątki (exceptions)

Programowanie Komponentowe Zarządzanie obiektami: kontenery

Operatory na rzecz typu TString

Programowanie obiektowe. Wykład 5. C++: szablony

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

Wstęp do programowania

1 Podstawy c++ w pigułce.

STL Standardt Template Library (wprowadzenie)

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

Technologie programowania Wykład 4. Szablony funkcji Notes. Szablony funkcji Notes. Szablony funkcji Notes. Notes. Przemek Błaśkiewicz.

ZASADY PROGRAMOWANIA KOMPUTERÓW

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

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

ALGORYTMY I STRUKTURY DANYCH

Szablon klasy std::list

Wstęp do Programowania 2

Abstrakcyjne struktury danych w praktyce

TEMAT : KLASY DZIEDZICZENIE

Kontenery i iteratory. Wykorzystanie kontenerów w praktyce.

Paradygmaty programowania. Paradygmaty programowania

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

Programowanie - wykład 4

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

Wykład 8: klasy cz. 4

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

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

Wartości domyślne, szablony funkcji i klas

Język C++ zajęcia nr 2

Programowanie w języku C++

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

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.

WYKŁAD 12. Wzorce projektowe czynnociowe State Mediator

Wstęp do Programowania 2

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

Część 4 życie programu

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

Język ludzki kod maszynowy

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

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

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

Wykład 4. Klasa List Kolejki Stosy Słowniki

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

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

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

Functionalization. Funkcje w C. Marcin Makowski. 30 listopada Zak lad Chemii Teoretycznej UJ

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

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

PROGRAMOWANIE OBIEKTOWE W C++ cz. 2. Dziedziczenie, operacje wej cia-wyj cia, przeładowanie operatorów.

Metody Metody, parametry, zwracanie wartości

Programowanie obiektowe, wykład nr 7. Przegląd typów strukturalnych - klasy i obiekty - c.d.

1 Podstawy c++ w pigułce.

Transkrypt:

Wzorce (szablony) Wzorce pozwalaj na okrelenie, za pomoc pojedynczego fragmentu kodu, całej gamy powizanych (przecionych) funkcji nazywanych funkcjami wzorcowymi lub powizanych kas nazywanych klasami wzorcowymi. Moemy napisa pojedynczy wzorzec funkcji dla funkcji sortowanie tablicy, a C++ wygeneruje automatycznie oddzielne funkcje wzorcowe porzdkujce tablic int, tablic float, tablic napisów i tak dalej. Moemy napisa pojedynczy wzorzec klasy dla klasy stosu, co spowoduje, e C++ automatycznie wygeneruje oddzielne klasy wzorcowe, na przykład klas stosu dla int, klas stosu dla float, czy klas stosu dla napisów string. Naley zwróci uwag na rónic pomidzy wzorcem funkcji/klasy, a funkcj/klas wzorcow. Wzorce funkcji i klas s tylko szablonem w oparciu o który krelimy kształt. Funkcje i klasy wzorcowe s niczym tak jakby przekalkowane, lecz oddzielne rysunki zawierajce ten sam kształt, które mog, na przykład, zosta pomalowane na róne kolory. Wszystkie definicje wzorców zaczynaj si od słowa kluczowego template poprzedzajcego zawart w nawiasach ktowych (<i>) list parametrów formalnych wzorca funkcji. Kady z tych parametrów, reprezentujcy typ, musi by poprzedzony słowem kluczowym class, tak jak przedstawiono poniej: template<class T> definicja wzorca lub template<class TypElementu> definicja wzorca lub template<class TypElementu1, class TypElementu2> definicja wzorca Parametry formalne w definicji wzorca wykorzystywane s (podobnie jak argumenty typów wbudowanych i zdefiniowanych przez uytkownika) do okrelenia typów wykorzystanych w definicji wzorca. Zwrómy uwag, e słowo kluczowe class wykorzystywane do okrelenia typów parametrów wzorca oznacza tu "kady typ wbudowany lub typ zdefiniowany przez uytkownika". Wzorce funkcji Wzorce funkcji stosowane s do wykonywania identycznych operacji na rónych typach danych. Programista pisze pojedyncz definicje wzorzec danej funkcji. Kompilator opierajc si na typach argumentów dostarczonych w jej wywołaniu, automatycznie generuje oddzielny kod wynikowy funkcji do odpowiedniej obsługi kadego wywołania.

Zbadajmy wzorzec funkcji druktabl 1. template<class T> 2. void druktabl(const T *tablica, const int licznik) 3. 4. for (int i=0; i< licznik ; i++) 5. cout<<tablica[i]<<" "; 6. 7. cout<<endl; 8. Wzorzec funkcji druktab deklaruje pojedynczy parametr formalny T (T moe by dowolnym wanym identyfikatorem) dla typu tablicy drukowanej przez funkcj druktabl. T jest tu parametrem typu. Gdy kompilator wykryje w kodzie ródłowym programu wywołanie tej funkcji, typ jej pierwszego argumentu staje si substytutem T w definicji wzorca, a C++ tworzy kompletn funkcje wzorcow dla druku tablicy zawierajcej okrelony typ danych. Nastpnie nowo utworzona funkcja zostaje skompilowana. Na przykład, realizacja dla typu int wyglda nastpujco: void druktabl(const int *tablica, const int licznik) for(int i=0; i<licznik; i++) cout<<tablica[i]<<" "; cout<<endl; Kady fragment formalny w definicji wzorca funkcji powinien wystpi przynajmniej raz na licie parametrów funkcji. Natomiast jego nazwa moe wystpi tylko raz na licie parametrów w nagłówku wzorca. Nie musi by ona unikatowa dla jednej funkcji wzorcowej. Przykład: #include <iostream.h> void druktabl(const int *tablica, const int licznik) for ( int i = 0; i < licznik; i++ ) cout << tablica[ i ] << " "; cout << endl;

int main() int a[5] = 1, 2, 3, 4, 5 ; double b[ 5] = 1.1, 2.2, 3.3, 4.4, 5.5 ; char c[5] = "asdfg"; druktabl ( a, 5 ); // funkcja wzorcowa dla int druktabl ( b, 5 ); // funkcja wzorcowa dla double druktabl ( c, 5 ); // funkcja wzorcowa dla char return 0; W tym przykładzie, mechanizm wzorców uwalnia programist od koniecznoci pisania trzech oddzielnych funkcji przecionych. Wzorce klas Wzorce klas s nazywane typami parametryzowanymi (ang. parametrized types), poniewa wymagaj jednego lub wicej parametrów do okrelenia, jak dostosowa wzorzec, klasy ogólnej do formy okrelonych klas wzorcowych. Programista, który pragnie stworzy szereg klas wzorcowych, moe po prostu napisa jedn definicje wzorca klasy. Za kadym razem, gdy potrzebuje nowej realizacji dla okrelonego typu danych, stosuje prost, zwizł notacje i kompilator tworzy kod ródłowy dla potrzebnej klasy wzorcowej. Na przykład, jeden wzorzec klasy Stos moe sta si podstaw do utworzenia szeregu, wykorzystywanych w programie, klas o rónych wartociach (jak Stos double, Stos int, Stos char, Stos pracownik itd.). Zwrómy uwag na definicje wzorca klasy Stos na poniszym rysunku. Wyglda ona jak zwykła definicja klasy, jest tylko poprzedzona nagłówkiem template<class T> w celu okrelenia, e jest to definicja wzorca klasy z parametrem typu T wskazujcym rodzaj tworzonej klasy Stos. Programista nie musi wykorzystywa jako identyfikatora T moe by tu zastosowany dowolny. Typ elementu przechowywanego w klasie Stos jest okrelony jako T w nagłówku klasy i definicjach funkcji składowych. Za chwil zobaczymy, jak T zostaje powizane z okrelonym typem, jak double lub int.

#ifndef TStos1_H #define TStos1_H // #include <iostream.h> // class Stos public: Stos( int = 10 ); // domylny konstruktor (Stos size 10) ~Stos() delete [] StosPtr; // destructor bool push( const T& ); // umie element na stosie bool pop( T& ); // pobierz element ze stosu private: int size; // ilo elementów na stosie int top; // połoenie elementu na szczycie stosu T *StosPtr; //wskanik na stos // bool isempty() const return top == -1; //funkcje pomocnicze bool isfull() const return top == size - 1; // ; // // Constructor with default size 10 Stos< T >::Stos( int s ) size = s > 0? s : 10; top = -1; //Pocztkowo stos jest pusty StosPtr = new T[ size ]; // alokacja miejsca dla elementów // Umie elementy na stosie // zwró 1 jełi operacja przebiegła pomylnie, 0 w przeciwnym przypadku bool Stos< T >::push( const T &pushvalue ) if (!isfull() ) StosPtr[ ++top ] = pushvalue; // umie na stosie return true; //udane umieszczenie return false; //nieudane umieszczenie //Pobierz element ze stosu bool Stos< T >::pop( T &popvalue )

if (!isempty() ) popvalue = StosPtr[ top-- ]; //usu element ze stosu return true; // udane pobranie return false; //nieudane pobranie #endif Rozwamy teraz program obsługi (funkcj main) testujcy wzorzec klasy Stos. Rozpoczyna si on od realizacji doublestos o wielkoci 5 elementów. Obiekt ten jest zadeklarowany jako klasa Stos<double> (wymawiaj Stos typu double ). Kompilator kojarzy typ double z parametrem typu T we wzorcu w celu utworzenia kodu ródłowego klasy Stos dla typu double. Chocia program nie widzi tego kodu ródłowego, jest dołczany do niego i kompilowany. #include <iostream.h> #include "tstos1.h" int main() Stos< double > doublestos( 5 ); double f = 1.1; cout << "Umieszczenie elementów na stosie doublestos\n"; while ( doublestos.push( f ) ) // udana operacja zwraca true cout << f << ' '; f += 1.1; cout << "\nstos jest pełny. Nie mona umieci " << f << "\n\npobieranie elementów ze stosu doublestos\n"; while ( doublestos.pop( f ) ) // udana operacja zwraca true cout << f << ' '; cout << "\nstos jest pusty. Nie mona nic pobra \n"; Stos< int > intstos; int i = 1; cout << "\numieszczanie elementów na stosie intstos\n"; while ( intstos.push( i ) ) // udana operacja zwraca true cout << i << ' '; ++i; cout << "\nstos jest pełny. Nie mona umieci " << i

<< "\n\npobieranie elementów ze stosu intstos\n"; while ( intstos.pop( i ) ) //udana operacja zwraca true cout << i << ' '; cout << "\nstos jest pusty nie mona nic pobra\n"; return 0; Program obsługi kolejno umieszcza wartoci double 1.1, 2.2, 3.3, 4.4 i 5.5 na stosie doublestos. Ptla push koczy si, gdy program ten usiłuje umieci szóst warto (stos jest pełny, poniewa został utworzony do przechowywania maksymalnie 5 elementów). Nastpnie program pobiera ze stosu pi wartoci. Program próbuje pobra szóst warto, ale doublestos jest ju pusty, wic ptla pop koczy si. Nastpnie, za pomoc deklaracji Stos<int> intstos program realizuje stos intstos dla liczb całkowitych (wymawiaj intstos to stos typu int ). Poniewa wielko stosu nie jest okrelona, przyjta zostaje domylna wielko 10, zdefiniowana w domylnym konstruktorze. I znów, program w ptli umieszcza wartoci na stosie intstos, do momentu zapełnienia go, a nastpnie pobiera je, a opróni stos. Podobnie jak poprzednio, wartoci pobierane s w kolejnoci ostatnia wpisana, pierwsza pobrana. Kada definicja funkcji składowej, znajdujca si poza nagłówkiem wzorca klasy, rozpoczyna si od nagłówka template<class T> Kada definicja funkcji jest podobna do zwykłej definicji, z wyjtkiem tego, e typ elementu Stos wymieniany jest zawsze ogólnie jako parametr typu T. Operator zasigu jest wykorzystywany w nazwie wzorca klasy Stos<T> do powizania definicji funkcji z zasigiem wzorca klasy. W tym przypadku, nazwa klasy to Stos<T>. Gdy realizowana jest klasa doublestos typu Stos<double>, konstruktor Stos wykoystuje new do utworzenia tablicy elementów typu double reprezentujcych stos. Instrukcja stosptr = new T[size]; w definicji wzorca klasy Stos jest definiowana przez kompilator w klasie wzorcowej Stos<double> jako stosptr = new double[size]; Zwrómy uwag, e kod funkcji main jest podobny zarówno przy wykoystaniu z doublestos w pocztkowej czci main, jak i przy uyciu intstos w jego dalszej czci. Standardowa biblioteka wzorców (STL Standard Template Library) Pliki nagłówkowe zasobników Biblioteki Standardowej <vector> <list> <deque> <stack>

<map> <set> <bitset> Zasobnik sekwencyjny Vector Klasa vector zawiera struktur danych z ssiadujcym umiejscowieniem w pamici. Umoliwia w ten sposób wydajny, bezporedni dostp do dowolnego elementu wektora przez operator indeksu [], dokładnie jak w surowej tablicy C lub C++. Klasa vector jest najczciej uywana, kiedy dane w zasobniku musz by sortowane i łatwo dostpne przez indeks. Kiedy pami vector zostaje wyczerpana, vector automatycznie przydziela wikszy cigły obszar pamici, kopiuje oryginalne elementy do nowej pamici i zwalnia star. Zasobnik sekwencyjny list Zasobnik sekwencyjny list umoliwia wydajn implementacje operacji wstawiania i usuwania z dowolnej jego pozycji. Jeli wikszo wstawie i usuni zachodzi na kocach zasobnika, struktura danych deque przekazuje bardziej efektywn implementacj. Klasa list jest implementowana jako lista z dwukierunkowymi odnonikami tj. kady wzeł listy zawiera wskanik do poprzedniego i nastpnego. To umoliwia klasie list obsług dwukierunkowych iteratorów, które pozwalaj na przechodzenie przez zasobnik zarówno do przodu, jak i w odwróconym porzdku. Dowolny algorytm, który wymaga iteratorów wejciowych, wyjciowych, do przodu lub dwukierunkowych moe operowa na obiekcie typu list. Wiele z funkcji składuwych list manipuluje elementami zasobnika, jak uporzdkowanym zbiorem elementów. Zasobnik sekwencyjny deque Klasa deque dostarcza bazdzo poytecznych klas vector i list w jednym zasobniku. Termin deque jest skrótem kolejki dwukierunkowej. Klasa deque jest równie zaimplementowana w celu dostarczenia wydajnego indeksowanego dostpu (z uyciem indeksu) do czytania i modyfikowania swoich elementów bardzo podobnie do klasy vector. Klasa deque jest równie implementowana do efektywnych operacji wstawiania na jej pocztku i kocu bardzo podobnie do klasy list (chocia list ma równie moliwo wydajnego usuwania i wstawiania w rodku obiektu typu list). Klasa deque stosuje obsług iteratorów o dostpie bezporednim, wic jej obiekty mog by uywane ze wszystkimi algorytmami STL. Jednym z najpowszechniejszych zastosowa deque jest utrzymanie kolejki elementów pierwszy-wyszedł-pierwszy-wszedł (FIFO). Dodatkowa pami dla deque moe by przydzielana na obu kocach obiektu deque w blokach pamici, które s zazwyczaj trzymane jako tablice wskaników do tych bloków. Odpowiednio do nie ssiadujcego rozmieszczenia pamici klasy deque, iterator tej klasy musi by bardziej inteligentny od wskaników uywanych do iteracji przez klas vector lub dla opartych na wskanikach tablic. Zasobniki skojarzeniowe (asocjacyjne)

Zasobniki skojarzeniowe STL umoliwiaj bezporedni dostp do przechowywania i odzyskiwania elementów przez klucze (czsto nazywane kluczami wyszukiwawczymi). Cztery zasobniki skojarzeniowe to multiset, set, multimap i map. W kadym z nich, klucze s utrzymane w posortowanym porzdku. Iterowanie przez zasobnik asocjacyjny bada go w jego własnym porzdku sortowania. Klasy multiset i set umoliwiaj operacje do manipulowania zestawami danych, gdzie te wartoci s kluczami nie ma oddzielnej wartoci skojarzeniowej z kadym kluczem. Główn rónic midzy multiset a set jest to, e multiset dopuszcza do duplikowania kluczy, a set nie. Zasobnik skojarzeniowy multiset Zasobnik skojarzeniowy multiset słuy do szybkiego zapamitywania i odzyskiwania kluczy oraz dopuszcza ich duplikowanie. Uporzdkowanie elementów jest okrelone przez obiekt funkcji porównania. Dla przykładu, w obiekcie multiset typu całkowitego elementy mog by sortowane w porzdku rosncym przez porzdkowanie kluczy za pomoc obiektu funkcji less<int>. Typ danych kluczy we wszystkich zasobnikach asocjacyjnych musi poprawnie obsługiwa porównanie w oparciu o okrelony obiekt funkcji porównania klucze sortowane za pomoc less<int> musz obsługiwa porównanie za pomoc iteratora <. Jeeli klucze uyte w zasobnikach asocjacyjnych s typu danych zdefiniowanych przez programist, typy te musz dostarcza odpowiednie operatory porównania. Bibliografia [1] Harvey M. Deitel, Paul J. Deitel - Arkana C++ Programowanie.