22
Objektno-orijentisano programiranje Šabloni (Templates)

OOP Templejti

Embed Size (px)

DESCRIPTION

Elektronski fakultet

Citation preview

Page 1: OOP Templejti

Objektno-orijentisano programiranje

Šabloni (Templates)

Page 2: OOP Templejti

Kako smo došli u situaciju da nam šabloni uopšte trebaju? Recimo da je potrebno da napišemo funkciju koja će

određuje koji je od data dva podatka veći. Ukoliko se radi o celobrojnim podacima, funkcija bi izgledala:

int max (int i, int j){ return i>j ? i : j;}

Međutim, šta ako umesto celih imamo realne brojeve? Onda bi funkcija izgledala ovako:

float max (float i, float j){ return i>j ? i : j;}

Page 3: OOP Templejti

Razlike između ove dve funkcije se svode na sistematsko zamenjivanje oznake tipa unutar cele definicije fukcije. To je rutinski posao i on se može automatizovati korišćenjem šablonskih ili generičkih funkcija.

Primer generičke funkcije za gornji primer bi bio:

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

Srećom, u jeziku C++ postoji ugrađeni mehanizam za šablone

Page 4: OOP Templejti

Šablonske (generičke) funkcije Prvi red u kodu sa prethodnog slajda:

template <class T>

definiše klasu T kao formalni argument koji će biti zamenjen stvarnim argumentom u trenutku korišćenja šablona. Na primer, ukoliko se pozove max(5,8), T će biti tip int.

Funkcije ili klase opisane pomoću šablona nazivaju se generičke funkcije ili generičke klase. Na osnovu njih se kasnije generišu konkretne funkcije ili klase.

Page 5: OOP Templejti

Kako izgledaju i čemu služe šablonske funkcije i klase Opšti oblik za šablone funkcija ili klasa je:

template < argument, argument, ... > opis

Argumenti mogu da označavaju tipove ili konstante. Opšti oblik argumenata je:

class identifikator_tipa (npr. class T)ilioznaka_tipa identifikator_konstante (npr. int k)

Opis može da bude deklaracija (prototip) ili definicija generičke funkcije (odnosno klase) čiji se šablon opisuje.

Šabloni mogu značajno da povećaju fleksibilnost i da smanje veličinu koda.

Page 6: OOP Templejti

Generisanje funkcija Funkcije na osnovu zadatog šablona se generišu:

automatski - kad se naiđe na poziv generičke f-je sa stvarnim argumentima koji mogu da se uklope u šablon bez konverzije tipova argumenata.

na zahtev programera - navođenjem deklaracije (prototipa) za datu generičku f-ju sa željenim argumentima.

Zaobilaženje generisanja funkcija na osnovu šablona postiže se navođenjem definicije odgovarajuće obične funkcije koju prevodilac mora da nađe pre nego što izvrši generisanje na osnovu šablona.

Primer:float max (float, float); // eksplicitni zahtev za generisanjefloat g = max (i, f);max<float>(i, f);

Page 7: OOP Templejti

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;}

Page 8: OOP Templejti

Tipski i netipski parametri šablona Tipski parametri se navode kao instanca neke

nedeklarisane klase (kao na primer class Cvet)

Kada dođe do pravljenja primeraka šablona, tipski parametri (kao onaj class Cvet) zamenjuju se stvarnim tipovima podataka – bilo ugrađenim (int, double, char*) ili korisnički definisanim (transport, vector <int>*)

Netipski parametar šablona sadrži uobičajenu deklaraciju parametara. Netipski parametar šablona označava potencijalnu vrednost. Ova vrednost predstavlja konstantu u definiciji šablona.

Videti primer na sledećem slajdu.

Page 9: OOP Templejti

Tipski i netipski parametri šablona - primer Ovde je class Cvet tipski, a int velicina netipski

parametar, odnosno konstantna vrednost koja postavlja veličinu niza:

template <class Cvet, int velicina>

Kada dođe do pravljenja primeraka šablona funkcije min, vrednost size zameniće se konstantnom vrednošću u vreme kompajliranja.

Cvet min(Cvet niz[velicina])

Page 10: OOP Templejti

Šablonska funkcija min – ceo kodtemplate <class Cvet, int velicina>Cvet min(const Cvet niz[velicina]){/* Parametrizovana funkcija za pronalaženje minimalne

vrednosti u nizu */

Cvet minvrednost = niz[0];for(int i = 1; i < velicina; i++){

if(niz[i] < minvrednost)minvrednost = niz[i];

}

return minvrednost;}

Page 11: OOP Templejti

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){

// Pogrešno! Redefinicija šablonskog parametra.typedef double Type;

Type tmp = a < b ? a : b;return tmp;

}

Naziv tipskog parametra se može koristiti za određivanje tipa rezultata u šablonu funkcije:

template <class Type, class T2, class T3>Type min (T2 a, T3 b)

Page 12: OOP Templejti

Napomene Naziv parametra šablona se može koristiti samo jednom u istoj

listi parametara u šablonu. Dakle, sledeći kod je neispravan:

template <class Type, class Type>Type min (Type a, Type b)

Međutim naziv parametra šablona može se ponovo koristiti u deklaracijama ili definicijama drugih šablona. Dakle, sledeći kod je ispravan:

template <class Type>Type min (Type a, Type b)

template <class Type>Type max (Type a, Type b)

Page 13: OOP Templejti

Šabloni klasa Šablon klase je “uputstvo” za formiranje klase pri čemu su jedan ili

više tipova ili vrednosti parametrizovani. Pretpostavimo da želimo da definišemo klasu koja podržava

mehanizam rada sa redom čekanja (engleski Queue). Red čekanja je FIFO struktura.

Nazovimo našu klasu Queue i neka podržava sledeće 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()

Page 14: OOP Templejti

Šabloni klasa - dalje Definicija klase Queue tada može 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 hoćemo da elementi reda budu drugog tipa, a ne integer?

U tom slučaju učinićemo našu klasu templejtskom.

Page 15: OOP Templejti

Šablonska klasa Queuetemplate <class Type>class Queue{public:Queue();~ Queue();

Type remove();void add(const Type &newItem);bool is_empty();bool is_full();}

Page 16: OOP Templejti

Generisanje raznih klasa Queue na osnovu šablona Da biste generisali razne klase Queue koje sadrže 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 sadrže i tipske i netipske parametre

Sve napomene koje su date kod šablonskih funkcija važe i za templejtske klase

Page 17: OOP Templejti

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);

};

Page 18: OOP Templejti

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;}

Page 19: OOP Templejti

Zadatak 7. Napisati templejtsku klasu koja modelira niz sačinjen 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 sledeće 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 vraća broj elemenata niza Funkciju za uredjivanje elemenata niza u rastući

redosled

Page 20: OOP Templejti

Zadatak 7 – nastavak Takođe, kreirati klasu Animal koja od privatnih podataka ima

vrstu i težinu životinje, a od javnih sledeće metode: Default konstruktor koji težinu životinje na 0, a ime na prayan

string Konstruktor koji inicijaliyuje privatne atribute Destruktor Operator < koji poredi dve životinje po težini Operator = koji jedan objekat klase Animal dodeljuje drugom Operator << koji upisuje ime i težinu životinje u tekstualni tok

podataka. Operator >> koji učitava ime i težinu životinje iz tekstualnog

toka podataka. U glavnom programu kreirati po jedan niz sa elementima

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

Page 21: OOP Templejti

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

Klasu Vreme koja sadrži 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 sledeće prijateljske funkcije: operatorsku funkciju >> za učitavanje vremena iz tekstualnog toka

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

Page 22: OOP Templejti

Zadatak 8. Generičku (šablonsku ili templejtsku) klasu Vektor čiji su privatni

članovi broj elemenata u vektoru i njegovi elementi zapamćeni u dinamičkoj zoni memorije. Elementi vektora su proizvoljnog tipa. Javni članovi klase su sledeće funkcije: konstruktor koji postavlja veličinu vektora, destruktor, funkcija za učitavanje elemenata sa standardnog ulaza, operatorska funkcija – za oduzimanje dva vektora, operatorska funkcija = za dodelu jednog vektora drugom, funkcija za nalaženje pozicije minimalnog elementa u vektoru, funkcija za prikaz k-tog elemenata na standardni izlaz.

U funkciji main sa standardnog ulaza učitati broj učesnika 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 rezultujućem vektoru i vrednost tog elementa (tj. startni broj pobednika i vreme za koje je pre[ao stazu).