• Nie Znaleziono Wyników

Kolekcje i algorytmy

N/A
N/A
Protected

Academic year: 2021

Share "Kolekcje i algorytmy"

Copied!
15
0
0

Pełen tekst

(1)

- p. 1/15

Zaawansowane programowanie w C++ (PCP)

Wykład 6 - szablony.

dr in˙z. Robert Nowak

(2)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Kolekcje i algorytmy

Poj ˛ecia niezale˙zne od typu:

 kolekcje (np. listy)

 algorytmy (np. znajdowania najwi ˛ekszego elementu) Mechanizmy eliminuj ˛ ace redundancj ˛e kodu.

 „r ˛eczna” modyfikacja kodu

 wspólna klasa bazowa

 wykorzystanie szablonów

(3)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 3/15

„R ˛eczna” modyfikacja kodu

typedef int Element;//element przykładowego kontenera

class WektorInt { public:

explicit WektorInt(int size = 10);

//konstruktor kopiuj ˛ acy, operator przypisania, destruktor const Element& get(int idx) const;//Zwraca element o danym Element& get(int idx);//Zwraca element o danym indeksie //...

private:

Element* tab_; //Tablica przechowuj ˛ aca elementy wektora int size_;//Liczba elementów

int capacity_;//Wielko´ s´ c tablicy };

 konieczno´s´c r ˛ecznej zmiany kodu (bł ˛edy!)

 utrudnione wprowadzanie modyfikacji (wiele kopii kodu)

(4)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Klasa bazowa

#include ¨Object.h¨

class WektorObj { public:

explicit WektorInt(int size = 10);

//konstruktor kopiuj ˛ acy, operator przypisania, destruktor const Object& get(int idx) const;//Zwraca element o danym Object& get(int idx);//Zwraca element o danym indeksie //...

private:

Object** tab_; //Tablica przechowuj ˛ aca elementy wektora //...

};

Wady:

 narzuty pami ˛eciowe i czasowe

 problem typów wbudowanych

(5)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 5/15

Zastosowanie szablonów

tempate<class T> class Wektor { public:

explicit Wektor(int size = 10);

//konstruktor kopiuj ˛ acy, operator przypisania, destruktor

const T& get(int idx) const;//Zwraca element o danym indeksie T& get(int idx);//Zwraca element o danym indeksie

void add(const T& val);//Dodaje element na koniec kolekcji /* Dalsza cz˛ e´ s´ c interfejsu klasy */

private:

T* tab_; //Tablica przechowuj ˛ aca elementy wektora int size_;//Liczba elementów

int capacity_;//Wielko´ s´ c tablicy };

Wektor<int> v;//Kolekcja liczb całkowitych v.add(3); v.add(4);//Operacje na kolekcji

Wektor<Data> vd;//Kolekcja obiektów klasy Data

Wektor<Figura*> vf; //Kolekcja wska´ zników do klasy

(6)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Deklaracja szablonu klasy

Deklaracja szablonu:

 deklaracja-wzorca:

template < lista-parametrów-wzorca > deklaracja

 lista-parametrów-wzorca:

parametr-wzorca [,lista-parametrów-wzorca]

 parametr-wzorca:

class identyfikator [= id-typu ]

typename identyfikator [= id-typu ]

Przykłady:

template<class T> class Array { /* oparty o jeden typ */ };

template<typename T, typename U>

class Graf{ /* zale˙ zny od dwu typów */ };

template<typename T, typename U = int>

class BinTree{ /* Domy´ slny parametr szablonu */ };

(7)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 7/15

generowanie typu

nazwa-szablonu < typ [,typ] >

Przykłady:

Array<int> a;

std::vector<double> vd;

Graf<std::string, std::string> gr;

vector<vector<int> > vv;

Niejednoznaczno´sci:

 zbyt bliskie poło˙zenie ko ´ncz ˛ acych >, np.

vector<vector<int>> v;

 znak >> jest operatorem przesuni ˛ecia

 prawidłowe vector<vector<int> > v; (dodatkowa

spacja)

(8)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Szablony - wła ´sciwo ´sci

Szablony s ˛ a mechanizmem czasu kompilacji

 pozwalaj ˛ a współdzieli´c kod ´zródłowy

 brak narzutów czasowych w czasie wykonania Organizacja plików ´zródłowych

 definicja (a nie tylko deklaracja) szablonu musi by´c widoczna w miejscu u˙zycia

 organizacja plików ´zródłowych

Kod nie jest kompilowany, je˙zeli nie został u˙zyty

(9)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 9/15

Przykład: std::pair

Definicja znajduje si ˛e w <utility>

template<class _T1, class _T2>

struct pair {

typedef _T1 first_type;

typedef _T2 second_type;

_T1 first;//Pierwsza składowa _T2 second;//Druga składowa

pair() : first(), second() { }

pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { } };

Przykłady u˙zycia:

std::pair<std::string,bool> a(¨Ala¨,true);

a.first = ¨Ola¨;

a.second = false;

(10)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Szablony funkcji

Wzorce funkcji: pozwalaj ˛ a implementowa´c algorytmy niezale˙zne od typu

template<typename T>

void std::swap(T& a, T& b) { T tmp = a;

a = b;

b = tmp;

}

template<typename T>

void printAll(const vector<T>& v, std::ostream& os) { for(size_t i = 0; i != v.size(); ++i)

os << v[i] << ",";

os << endl;

}

(11)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 11/15

Argumenty wzorca funkcji

Istnieje mo˙zliwo´s´c wyznaczania argumentów wzorca z argumentów podanych w wywołaniu

template<typename T>

void printAll(const vector<T>& v, std::ostream& os) { /* ... * vector<int> w;

//dodanie elementów do wektora

printAll(w,cout);//printAll<int>(w,cout) template<typename T> T* przydziel()

{ /* Tworzy obiekt i zwraca wska´ znik */ }

int* pi = przydziel<int>(); //Niemo˙ zliwa automatyczna specjalizacja

(12)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Problem typu

Typowy problem - jawne wskazanie, ˙ze identyfikator jest typem

class Foo { public:

typedef int Element;

/* dalsza cz˛ e´ s´ c implementacji klasy Foo */

};

template<typename T> void f(const T& t) {

//Poni˙ zej bł˛ ednie zakłada, ˙ ze T::Element to nazwa składowej T::Element e = 0;

//...

//Poni˙ zej jawnie wskazano, ˙ ze T::Element to nazwa typu typename T::Element e = 0;

//...

};

(13)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 13/15

Szablony kontra hierarchia klas

U˙zywaj szablonów gdy:

 wa˙zne s ˛ a typy wbudowane

 nie mo˙zna utworzy´c wspólnej klasy podstawowej

 bardzo wa˙zna jest efektywno´s´c

 akceptowalna jest powtórna kompilacja przy dodawaniu nowego typu

W przeciwnym wypadku u˙zywaj hierarchii klas.

(14)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

Zasady tworzenia szablonów

1. zaimplementowa´c typ konkretny 2. przetestowa´c go

3. przekształci´c go w szablon

4. wygenerowa´c i przetestowa´c kilka ró˙znych typów

(15)

» Kolekcje i algorytmy

» „R ˛eczna” modyfikacja kodu

» Klasa bazowa

» Zastosowanie szablonów

» Deklaracja szablonu klasy

» generowanie typu

» Szablony - wła´sciwo´sci

» Przykład: std::pair

» Szablony funkcji

» Argumenty wzorca funkcji

» Problem typu

» Szablony kontra hierarchia klas

» Zasady tworzenia szablonów

» Podział kodu wzorca na pliki

- p. 15/15

Podział kodu wzorca na pliki

Plik ¨kontener.h¨ - definicja klasy

#ifndef KONTENER

#define KONTENER

template<typename T>

class Kontener { /* Definicja klasy i metod inline */ };

#include ¨kontener_impl.h¨

#endif

Plik ¨kontener_impl.h¨ - implementacja metod wzorca

//Nie ma zabezpiecze´ n przed wielokrotnym doł ˛ aczaniem template<typename T>

T& Kontener<T>::get(int index) { /* Definicja metody */ }

Plik ¨kontener.cpp¨ - kod niezale˙zny od typu T

Cytaty

Powiązane dokumenty