po w4szablony id 557614 Nieznany

background image

Programowanie obiektowe

Wykład 5. C++: szablony

background image

Szablony

Szablony to technika realizacji polimorfizmu na innym
poziomie niż za pomocą funkcji wirtualnych i dziedziczenia.

Mechanizm ten można rozumieć jako ’inteligentniejsze’
makrodefinicje.

Szablony nie są w bezpośredni sposób związane z
programowaniem obiektowym.

background image

Szablony funkcji

przykład problemu: definiujemy funkcję porównującą...

...liczby całkowite:

int compare(int a, int b)
{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

background image

Szablony funkcji

przykład problemu: definiujemy funkcję porównującą...

...liczby całkowite:

int compare(int a, int b)
{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

...liczby rzeczywiste:

int compare(float a, float b)
{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

background image

Szablony funkcji

przykład problemu: definiujemy funkcję porównującą...

...liczby całkowite:

int compare(

int

a,

int

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

...liczby rzeczywiste:

int compare(

float

a,

float

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

... i tak samo dla każdego innego typu

background image

Szablony funkcji

przykład problemu: definiujemy funkcję porównującą...

...liczby całkowite:

int compare(

int

a,

int

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

...liczby rzeczywiste:

int compare(

float

a,

float

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

... i tak samo dla każdego innego typu
... pod warunkiem, że ma zdefiniowany operator <

background image

Szablony funkcji

przykład problemu: definiujemy funkcję porównującą...

...liczby całkowite:

int compare(

int

a,

int

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

...liczby rzeczywiste:

int compare(

float

a,

float

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

...pudełka

class Pudelko
{
public:

float dl,sz,wy;
Pudelko(float d, float s, float w) : dl(d), sz(s), wy(w) {}
int operator<(Pudelko& p) { return dl*sz*wy < p.dl*p.sz*p.wy; }

};

int compare(

Pudelko

a,

Pudelko

b)

{ if(a<b) return 1; else if(b<a) return -1; else return 0; }

background image

Szablony funkcji

podstawowe informacje

szablon funkcji jest sparametryzowaną definicją funkcji

szablon funkcji definiuje się w zakresie globalnym

parametrem szablonu funkcji jest typ (klasa), bądź lista typów

wszystkie parametry szablonu muszą wystąpić w opisie
argumentów funkcji szablonowej (kompilator odnajduje
szablon na podstawie wywołania funkcji)

Składnia:

template< opis˙parametrów >

definicja funkcji

background image

Szablony funkcji

przykład

class Pudelko
{
public:

float dl,sz,wy;
Pudelko(float d, float s, float w) : dl(d), sz(s), wy(w) {}
int operator<(Pudelko& p) { return dl*sz*wy < p.dl*p.sz*p.wy; }

};

template <class T>
int compare(T a, T b)
{

if(a<b) return -1; else if(b<a) return 1; else return 0;

}

int main()
{

cout
<< compare(1,2) << endl

//-1

<< compare(1.5,2.5) << endl

//-1

<< compare(’a’,’b’) << endl

//-1

<< compare(Pudelko(1.0,2.0,2.0),Pudelko(2.0,1.5,4.2)) << endl;//-1

}

background image

Szablony funkcji

parametry

parametrem szablonu funkcji jest typ (klasa), bądź lista typów

wszystkie parametry szablonu muszą wystąpić w opisie
argumentów funkcji szablonowej (kompilator odnajduje
szablon na podstawie wywołania funkcji)

oprócz obowiązkowego użycia parametrów szablonu w opisie
argumentów funkcji szablonowej, można ich używać w
dowolnym miejscu w definicji tej funkcji (jako nazwy typu).

template<class S, class T>

T

* jakasfunkcja(S a, T b)

{

T

*l = new(

T

);

int r=sizeof(

S

);

...
return l;

}

background image

Szablony funkcji

jedynym ograniczeniem, jakie w definicji szablonu można
nałożyć na typy argumetów funkcji szablonowej jest by
niektóre z nich były takie same, np. szablon

template <class K, class L, class M>
void f(K a, L b, K c, M d)

...

pasuje do wywołania

f(3,’e’,5,"Ala")

ale do wywołania

f(3,’e’,’a’,"Ala")

nie.

background image

Szablony funkcji

jak to działa

natrafiając na wywołanie funkcji, kompilator sprawdza, czy
istnieje funkcja o podanej nazwie, liczbie i typie argumentów

jeśli nie, sprawdza, czy istnieje szablon pozwalający taką
funkcję wygenerować, jeśli tak – generuje odpowiednią funkcję

jeśli nie, sprawdza czy isnieje funkcja którą można dopasować
dokonując konwersji typów argumentów, jeśli tak, dokonuje
wiązania z zastosowaniem konwersji typów

background image

Szablony funkcji

sytuacje wyjątkowe

często zdarza się, że funkcje wygenerowane z szablonu będą
działać poprawnie (lub w ogóle będą poprawne) w większości
przypadków, ale nie we wszystkich

szablon z poprzedniego przykładu nie będzie działał poprawnie
dla typu char*

nie nadaje się on w ogóle np. dla typu

class Data {

public:
int dzien, miesiac, rok;

}

za względu na brak operatora <

cout

<< compare(1,2) << endl

// -1

<< compare(1.5,2.5) << endl

// -1

<< compare(’a’,’b’) << endl

// -1

<< compare(Pudelko(1.0,2.0,2.0),Pudelko(2.0,1.5,4.2)) << endl // -1
<< compare("Ala","Ola") << endl

// 1

(!)

<< compare((string)"Ala",(string)"Ola") << endl;

// -1

background image

Szablony funkcji

funkcje specjalizowane

wyjątki od sposobu generownia funkcji zdefiniowanego przez
szablon można zdefiniować pisząc funkcję specjalizowaną

funkcja specjalizowana to funkcja, której nazwa i typy
parametrów pasują do szablonu, tyle że jest jest to normalna
funkcja

background image

Szablony funkcji

funkcje specjalizowane

template <class T>
int compare(T a, T b)
{

if(a<b) return -1; else if(b<a) return 1; else return 0;

}

int compare(const char* a, const char* b)
{

return strcmp(a,b);

}

int main()
{

cout << compare(1,2) << endl

// -1

<< compare(1.5,2.5) << endl

// -1

<< compare(’a’,’b’) << endl

// -1

<< compare(Pudelko(1.0,2.0,2.0),Pudelko(2.0,1.5,4.2)) << endl // -1
<< compare("Ala","Ola") << endl

// -1

<< compare((string)"Ala",(string)"Ola") << endl;

// -1

}

background image

Szablony klas

podstawowe informacje

szablon klasy jest sparametryzowaną definicją klasy

szablon klasy definiuje się w zakresie globalnym

Składnia:

template< opis˙parametrów >
class nazwaklasy
{

...

};

background image

Szablony klas

przykład (bardzo typowy)

Szablon klasy Stos, którego parametrem jest typ elementów
przechowywanych na stosie.

template <class

T

>

class Stos
{
public:

Stos() : n(0)

}

Stos& push(

T

e) { dane[n++]=e; return *this; } // dodanie elementu

T

pop()

{ return dane[--n]; }

// pobranie elementu

int empty()

{ return n==0; }

// test czy pusty

operator int()

{ return n; }

// dodatkowy bajer

private:

T

dane[100];

int n;

};

background image

Szablony klas

klasa szablonowa

po zdefniowaniu szablonu klas

template< opis˙parametrów >
class nazwaklasy
{

...

};

nazwą klasy szablonowej jest nazwaklasy<parametry>

posługujemy się nią jak zwykłymi nazwami klas/typów

w momencie napotkania takiej nazwy, kompilator generuję
definicję klasy szablonowej dla podanych parametrów (jeśli
wcześniej już tego nie zrobił)

background image

Szablony klas

użycie klasy szblonowej

int main()
{

Stos<char>

stosznakow;

// generowana jest klasa Stos<char>

Stos<int>

stosliczb;

// generowana jest klasa Stos<int>

stosznakow.push(’A’).push(’l’).push(’a’);
stosliczb.push(1).push(2).push(3);

Stos<char>

drugistosznakow=stosznakow; // klasa Stos<char> już jest

while(stosznakow)

// bajer

{

cout << stosznakow.pop();

}
cout << endl;
while(stosliczb)
{

cout << stosliczb.pop();

}
cout << endl;

}

background image

Szablony klas

parametry

Szablon klasy może mieć wiele parametrów (separatorem jest
przecinek)

Parametrem szablonu klasy może być:

typ (class nazwa)

wartość całkowita stała (int nazwa)

template < class Typ, int rozmiar >

także stałe wyrażenie będące adresem obiektu globalnego lub
funkcji globalnej (rzadsze zastosowanie)

background image

Szablony klas

definicje metod klasy szablonowej poza ciałem klasy

definicje metod klasy szablonowej umieszczone poza ciałem
klasy są w istocie szablonami definicji metod

mają postać taką jak szablony funkcji, z tą oczywiście różnicą,
że ich nazwę poprzedza się nazwą klasy szablonowej

podobnie też jak w przypadku szablonów funkcji, można
definiować metody specjalizowane

background image

Szablony klas

definicje metod klasy szablonowej poza ciałem klasy

template <class T>
class Stos
{
public:

Stos();
Stos& push(T e);
T pop();

itd

private:

T dane[100];
int n;

};

template<class T>
Stos<T>::Stos() : n(0) {}

template<class T>
Stos<T>& Stos<T>::push(T e) { dane[n++]=e; return *this; }

template<class T>
T Stos<T>::pop()

{ return dane[--n]; }

itd.

background image

Szablony klas

definicje metod klasy szablonowej poza ciałem klasy
(lupa)

są to szablony metod

template<class T>

Stos<T>::Stos() : n(0) {}

template<class T>

Stos<T>& Stos<T>::push(T e) { dane[n++]=e; return *this; }

template<class T>

T Stos<T>::pop()

return dane[--n];

itd.

background image

Szablony klas

definicje metod klasy szablonowej poza ciałem klasy
(lupa)

nieodłączną częścią nazwy klasy szablonowej jest parametr(y)

template<class T>

Stos<T>

::Stos() : n(0) {}

template<class T>

Stos<T>

&

Stos<T>

::push(T e) { dane[n++]=e; return *this; }

template<class T>
T

Stos<T>

::pop()

return dane[--n];

itd.

background image

Szablony klas

definicje metod klasy szablonowej poza ciałem klasy
(lupa)

nazwa konstruktora (destruktora) nie jest nazwą klasy — bez
parametu

template<class T>
Stos<T>::

Stos

() : n(0) {}

template<class T>
Stos<T>& Stos<T>::push(T e) { dane[n++]=e; return *this; }

template<class T>
T Stos<T>::pop()

return dane[--n];

itd.

background image

Szablony klas

parametry nie będące typami – przykład

W szablonie stosów dodajemy parametr określający rozmiar.

template <class T,

int max

>

class Stos
{
public:

Stos() : n(0)

{}

Stos& push(T e) { dane[n++]=e; return *this; }
T pop()

{ return dane[--n]; }

int empty()

{ return n==0; }

operator int()

{ return n; }

private:

T dane[

max

];

int n;

};

int main()
{

Stos<char,

20

> stos;

stos.push(’A’).push(’l’).push(’a’);
while(stos) { cout << stos.pop(); }
cout << endl;

}

background image

Szablony klas

klasa szablonowa jako klasa bazowa

Klasa szablonowa może być klasą bazową innej klasy.

Klasa szablonowa może być klasą bazową w szablonie klasy.

template<class T>
class K
{

...

};

class L : K<int>
{

...

}

template<class S>
class M : K<int>
{

...

}

background image

Szablony klas

klasa szablonowa jako klasa bazowa

Klasa szablonowa może być klasą bazową innej klasy.

Klasa szablonowa może być klasą bazową w szablonie klasy.

template<class T>
class K
{

...

};

class L : K<int>
{

...

}

template<class S>
class M : K<int>
{

...

}

background image

Szablony klas

szablon klasy jako klasa bazowa

szablonu klasy można użyć jako klasy bazowej w innym
szablonie klasy

parametry szablonu klasy bazowej

muszą być parametrami

szablonu klasy pochodnej

albo muszą mieć ustaloną wartość

template<class T, int max>
class Stos
{

...

};

template<class

S

, int

max

>

class lepszystos : K<

S

,

max

>

{

...

}

template<class

S

>

class stosstulementowy : K<

S

,100>

{

...

}

background image

Szablony klas

szablon klasy jako klasa bazowa

szablonu klasy można użyć jako klasy bazowej w innym
szablonie klasy

parametry szablonu klasy bazowej muszą być parametrami
szablonu klasy pochodnej

albo muszą mieć ustaloną wartość

template<class T, int max>
class Stos
{

...

};

template<class S, int max>
class lepszystos : K<S,max>
{

...

}

template<class S>
class stosstulementowy : K<S,

100

>

{

...

}

background image

Szablony klas

składowe statyczne klas szablonowych

Każda instancja klasy szablonowej ma swój komplet składowych
statycznych.


Wyszukiwarka

Podobne podstrony:
PO lab 5 id 364195 Nieznany
po modernizacji id 364203 Nieznany
po w2 id 557612 Nieznany
po w3 id 557613 Nieznany
po w1 id 364234 Nieznany
ALF po paracetamolu id 55196 Nieznany
PO W1 2 id 364238 Nieznany
PO W3 id 364241 Nieznany
Lunar 100 dzien po dniu id 2739 Nieznany
po w1 id 557610 Nieznany
PO lab 6 id 364196 Nieznany
PO lab 5 id 364195 Nieznany
po modernizacji id 364203 Nieznany
po w2 id 557612 Nieznany
Po prostu PageMaker 7 id 364216 Nieznany
po w9 utf8 id 557617 Nieznany
po w13 utf8 id 557611 Nieznany
przewodnik po nomenklaturze id Nieznany

więcej podobnych podstron