You are on page 1of 22

Objektno-orijentisano programiranje

abloni (Templates)

Kako smo doli u situaciju da nam


abloni uopte trebaju?

Recimo da je potrebno da napiemo funkciju koja e


odreuje koji je od data dva podatka vei. Ukoliko se radi o
celobrojnim podacima, funkcija bi izgledala:
int max (int i, int j)
{
return i>j ? i : j;
}

Meutim, ta ako umesto celih imamo realne brojeve? Onda


bi funkcija izgledala ovako:
float max (float i, float j)
{
return i>j ? i : j;
}

Sreom, u jeziku C++ postoji


ugraeni mehanizam za ablone

Razlike izmeu ove dve funkcije se svode na


sistematsko zamenjivanje oznake tipa unutar cele
definicije fukcije. To je rutinski posao i on se moe
automatizovati korienjem ablonskih ili
generikih funkcija.

Primer generike funkcije za gornji primer bi bio:


template <class T>
T max (T i, T j)
{
return i>j ? i : j;
}

ablonske (generike) funkcije

Prvi red u kodu sa prethodnog slajda:


template <class T>
definie klasu T kao formalni argument koji e biti
zamenjen stvarnim argumentom u trenutku
korienja ablona. Na primer, ukoliko se pozove
max(5,8), T e biti tip int.

Funkcije ili klase opisane pomou ablona


nazivaju se generike funkcije ili
generike klase. Na osnovu njih se kasnije
generiu konkretne funkcije ili klase.

Kako izgledaju i emu slue


ablonske funkcije i klase

Opti oblik za ablone funkcija ili klasa je:


template < argument, argument, ... > opis

Argumenti mogu da oznaavaju tipove ili konstante. Opti oblik


argumenata je:
class identifikator_tipa (npr. class T)
ili
oznaka_tipa identifikator_konstante (npr. int k)

Opis moe da bude deklaracija (prototip) ili definicija generike


funkcije (odnosno klase) iji se ablon opisuje.

abloni mogu znaajno da poveaju fleksibilnost i da smanje


veliinu koda.

Generisanje funkcija

Funkcije na osnovu zadatog ablona se generiu:

automatski - kad se naie na poziv generike f-je sa stvarnim


argumentima koji mogu da se uklope u ablon bez konverzije
tipova argumenata.

na zahtev programera - navoenjem deklaracije (prototipa) za


datu generiku f-ju sa eljenim argumentima.

Zaobilaenje generisanja funkcija na osnovu ablona postie se


navoenjem definicije odgovarajue obine funkcije koju prevodilac
mora da nae pre nego to izvri generisanje na osnovu ablona.

Primer:
float max (float, float);
float g = max (i, f);
max<float>(i, f);

// eksplicitni zahtev za generisanje

Primer 1.
template <class Type>
Type min (Type a, Type b)
{
return a < b ? a : b;
}
int main()
{
// ok: min(int, int)
min(10, 20);
// ok: min(double, double)
min(10.0, 20.0);
return 0;
}

Napomena: Naziv parametra


ablonske funkcije NE MORA da
bude Type. Ispravno e raditi i
ovakava funkcija:
template <class Cvet >
Cvet min (Cvet a, Cvet b)
{
return a < b ? a : b;
}

Tipski i netipski parametri ablona

Tipski parametri se navode kao instanca neke


nedeklarisane klase (kao na primer class Cvet)

Kada doe do pravljenja primeraka ablona, tipski


parametri (kao onaj class Cvet) zamenjuju se stvarnim
tipovima podataka bilo ugraenim (int, double, char*)
ili korisniki definisanim (transport, vector <int>*)

Netipski parametar ablona sadri uobiajenu


deklaraciju parametara. Netipski parametar ablona
oznaava potencijalnu vrednost. Ova vrednost
predstavlja konstantu u definiciji ablona.

Videti primer na sledeem slajdu.

Tipski i netipski parametri ablona primer

Ovde je class Cvet tipski, a int velicina netipski


parametar, odnosno konstantna vrednost koja
postavlja veliinu niza:
template <class Cvet, int velicina>

Kada doe do pravljenja primeraka ablona


funkcije min, vrednost size zamenie se
konstantnom vrednou u vreme
kompajliranja.

Cvet min(Cvet niz[velicina])

ablonska funkcija min ceo kod


template <class Cvet, int velicina>
Cvet min(const Cvet niz[velicina])
{
/* Parametrizovana funkcija za pronalaenje minimalne
vrednosti u nizu */
Cvet minvrednost = niz[0];
for(int i = 1; i < velicina; i++)
{
if(niz[i] < minvrednost)
minvrednost = niz[i];
}
return minvrednost;
}

Napomene

Objekat ili tip koji su deklarisani u definiciji ablona funkcije ne


mogu nositi isti naziv kao i parametar ablona.
template <class Type>
Type min (Type a, Type b)
{
// Pogreno! Redefinicija ablonskog parametra.
typedef double Type;
Type tmp = a < b ? a : b;
return tmp;
}

Naziv tipskog parametra se moe koristiti za odreivanje tipa


rezultata u ablonu funkcije:
template <class Type, class T2, class T3>
Type min (T2 a, T3 b)

Napomene

Naziv parametra ablona se moe koristiti samo jednom u istoj


listi parametara u ablonu. Dakle, sledei kod je neispravan:
template <class Type, class Type>
Type min (Type a, Type b)

Meutim naziv parametra ablona moe se ponovo koristiti u


deklaracijama ili definicijama drugih ablona. Dakle, sledei
kod je ispravan:
template <class Type>
Type min (Type a, Type b)
template <class Type>
Type max (Type a, Type b)

abloni klasa

ablon klase je uputstvo za formiranje klase pri emu su jedan ili


vie tipova ili vrednosti parametrizovani.
Pretpostavimo da elimo da definiemo klasu koja podrava
mehanizam rada sa redom ekanja (engleski Queue). Red ekanja
je FIFO struktura.
Nazovimo nau klasu Queue i neka podrava sledee operacije:

proveravanje da li je red pun


bool is_full()

proveravanje da li je red prazan


bool is_empty()

dodavanje elementa u red


void add(item)

izbacivanje elementa iz reda


item remove()

abloni klasa - dalje

Definicija klase Queue tada moe da izgleda ovako


class Queue
{
public:
Queue();
~ Queue();
int remove();
void add(const int &newItem );
bool is_empty();
bool is_full();
}

Postavlja se pitanje ta da radimo ako hoemo da elementi reda budu


drugog tipa, a ne integer?
U tom sluaju uiniemo nau klasu templejtskom.

ablonska klasa Queue


template <class Type>
class Queue
{
public:
Queue();
~ Queue();
Type
void
bool
bool
}

remove();
add(const Type &newItem);
is_empty();
is_full();

Generisanje raznih klasa Queue na


osnovu ablona

Da biste generisali razne klase Queue koje sadre cele


brojeve, kompleksne brojeve i nizove znakova, treba
napisati:
Queue <integer> qi;
Queue <string> qs;
Queue < Complex <double> > qcd;

Ovde je jedino neophodno da postoji prethodno


definisana templejtska klasa complex
Templejtske klase, kao i templejtske funkcije, mogu
da sadre i tipske i netipske parametre
Sve napomene koje su date kod ablonskih funkcija
vae i za templejtske klase

Primer jo jedne ablonske klase

Deklaracija klase (Vektor.h)

template <class T, int k>


class Vektor
{
T element [k];
public:
Vektor();
T& operator[] (int i);
};

Definicija lanova klase (Vektor.h)

template <class T, int k>


Vektor<T, k>::Vektor ()
{
}
template <class T, int k>
T& Vektor<T, k>::operator[] (int i)
{
if(i < k)
return element[i];
return 0;
}

Zadatak 7.

Napisati templejtsku klasu koja modelira niz sainjen od


elemenata proizvoljnog tipa. Kao privatne podatke ova klasa
treba da ima niz elemenata proizvoljnog tipa i broj
elemenata tog niza. Kao javne, klasa treba da ima sledee
funkcije:

Default konstruktor koji zauzima prostor za 10


elemenata i postavlja broj elemenata niza na 10

Konstruktor sa jednim celobrojnim parametrom size, koji


zauzima prostor za size elemenata i broj elemenata niza
postavlja na size

Konstruktor za kopiranje

Destruktor

Operator[] za pristup elementima niza

Int GetSize() metodu koja vraa broj elemenata niza

Funkciju za uredjivanje elemenata niza u rastui


redosled

Zadatak 7 nastavak

Takoe, kreirati klasu Animal koja od privatnih podataka


ima vrstu i teinu ivotinje, a od javnih sledee metode:

Default konstruktor koji teinu ivotinje na 0, a ime na prayan


string
Konstruktor koji inicijaliyuje privatne atribute
Destruktor
Operator < koji poredi dve ivotinje po teini
Operator = koji jedan objekat klase Animal dodeljuje drugom
Operator << koji upisuje ime i teinu ivotinje u tekstualni tok
podataka.
Operator >> koji uitava ime i teinu ivotinje iz tekstualnog
toka podataka.

U glavnom programu kreirati po jedan niz sa elementima


celobrojnog tipa i sa elementima klase Animal, uitati
elemente nizova sa standardnog ulaza, urediti nizove i
elemente uredjenih nizova prikazati na standatdni izlaz

Zadatak 8.
Na programskom jeziku C++ napisati program za odredjivanje
pobednika jedne trke u brzom skijanju. U okviru zadatka kreirati:

Klasu Vreme koja sadri privatne atribute: sat (ija se vrednost


nalazi u opsegu 0-24), minut (0-60) i sekund (0-60), i javne
metode:

konstruktor bez argumenata


konstruktor koji sve atribute postavlja na zadate vrednosti,
operatorsku funkciju - za oduzimanje dva vremena,
operatorsku funkciju = za dodelu jednog objekta klase Vreme drugom,
operatorsku funkciju < za poredjenje dva vremena.

Definisati i sledee prijateljske funkcije:

operatorsku funkciju >> za uitavanje vremena iz tekstualnog toka


podataka,
operatorsku funkciju << za upis vremena u tekstualni tok podataka.

Zadatak 8.

Generiku (ablonsku ili templejtsku) klasu Vektor iji su privatni


lanovi broj elemenata u vektoru i njegovi elementi zapameni u
dinamikoj zoni memorije. Elementi vektora su proizvoljnog tipa.
Javni lanovi klase su sledee funkcije:

konstruktor koji postavlja veliinu vektora,


destruktor,
funkcija za uitavanje elemenata sa standardnog ulaza,
operatorska funkcija za oduzimanje dva vektora,
operatorska funkcija = za dodelu jednog vektora drugom,
funkcija za nalaenje pozicije minimalnog elementa u vektoru,
funkcija za prikaz k-tog elemenata na standardni izlaz.

U funkciji main sa standardnog ulaza uitati broj uesnika u trci,


vektor startnih vremena i vektor vremena prolazaka kroz cilj.
Odrediti razliku ova dva vektora i na standardni izlaz prikazati
poziciju minimalnog elementa u rezultujuem vektoru i vrednost
tog elementa (tj. startni broj pobednika i vreme za koje je pre[ao
stazu).

You might also like