Uvod u Objektno Orijentirano Programiranje

46
Uvod u objektno-orijentirano programiranje u programskom jeziku C++ jeziku C++ 8.4.2007 autor: dr. sc. Zvonimir Vanjak

Transcript of Uvod u Objektno Orijentirano Programiranje

Page 1: Uvod u Objektno Orijentirano Programiranje

Uvod u objektno-orijentirano programiranje u programskom jeziku C++jeziku C++

8.4.2007 autor: dr. sc. Zvonimir Vanjak

Page 2: Uvod u Objektno Orijentirano Programiranje

Evolucija programskih jezika

prva generacija – strojni jezikdruga generacija asemblerdruga generacija – asemblertreća generacija – Pascal, C, Fortran, Algol, LISP, ...

uvodi se paradigma proceduralnog, strukturnog i modularnog programiranjapojavljuju se i višenamjenski jeziciobjektno-orijentirani jezici kao nova paradigma razvoja (- Smalltalk, C++, Java, C#

četvrta generacija – 4GL jezicijezici specijalizirani za određenu domenu problema

Algoritmi i strukture podataka, 2006/07. 8.4.2007 2 / 46

Page 3: Uvod u Objektno Orijentirano Programiranje

Razvoj tipičnog programera

uglavnom započinje učenjem nekog programskog jezika treće generacijegeneracije

Basic, Pascal, Csrećom učenje strojnog jezika i asemblera je iza nas (☺)srećom, učenje strojnog jezika i asemblera je iza nas (☺)

koristi se paradigma nestrukturiranog programiranjači j i j lih i j d t ih k ji t j d započinje se pisanjem malih i jednostavnih programa koji se sastoje od

slijeda naredbi i djeluju nad zajedničkim skupom podataka

Algoritmi i strukture podataka, 2006/07. 8.4.2007 3 / 46

Page 4: Uvod u Objektno Orijentirano Programiranje

Proceduralna paradigma - I

osnovni korak je uvođenje funkcija koje su izgrađene kao skup naredbi i koje imaju dobro definiran ulaz i izlaz (već viđeno na PIPI-ju)rješavamo se problema ponavljanja programskog kôda!!!

definiramo ga na jednom mjestu i zatim samo pozivamo funkciju kad nam zatreba takva funkcionalnost

Glavni program

Podaci

Procedura 1 Procedura 2 Procedura 3

Lokalni podaci Lokalni podaci Lokalni podaci

Algoritmi i strukture podataka, 2006/07. 8.4.2007 4 / 46

Page 5: Uvod u Objektno Orijentirano Programiranje

Proceduralna paradigma - II

primjeri:matematičke funkcije – sin cosmatematičke funkcije sin, cosfunkcije za U/I – printf, fwritefunkcije za rad s grafikom - DrawLine, DrawCirclej g ,

a što ako je netko već implementirao takve funkcije?!možemo ih (jednostavno) iskoristiti!(j )- većina razvojnih okruženja dolazi s ugrađenom gomilom biblioteka takvih funkcija

reusability – mogućnost ponovnog iskorištavanja programskog kôday g g j g g“write once, use everywhere”ali, nije sve tako jednostavno javlja se problem organizacije velikog broja funkcija u smislene cjeline!

Algoritmi i strukture podataka, 2006/07. 8.4.2007 5 / 46

Page 6: Uvod u Objektno Orijentirano Programiranje

Modularno programiranje

procedure srodne funkcionalnosti grupiraju se u module koji mogu imati vlastite podatkep

Modul 1 Program

PodaciPodaci 1 Podaci

Procedura 1

Podaci 1

Modul 2Lokalni podaci

P d i 1

Procedura 2 Procedura 3

Podaci 1

Lokalni podaci Lokalni podaci

Algoritmi i strukture podataka, 2006/07. 8.4.2007 6 / 46

Page 7: Uvod u Objektno Orijentirano Programiranje

I dalje nije sve idealno!

teško je napraviti modul da bude dobro definirana i zatvorena jedinica funkcionalnosti!programski jezici imaju vrlo “tanku” (i često nejasnu) definiciju modula

npr. u C-u modul može biti:- .h datoteka s pripadajućom .cpp datotekom- biblioteka funkcija koja se statički povezuje (linka) u naš program

Windows DLL biblioteka- Windows DLL bibliotekakoncept modula je najčešće implementacijski detalj programskog okruženja u kojem radimo i nije potpuno integriran u sam programski jezik

osnovni problem je što funkcije i podaci ugrađeni u modul nisu povezani u konkretne programske entitete koji bi predstavljali razumljiv i jasan koncept za k j j k i ik d lkrajnje korisnike modula

standardni <stdio.h> predstavlja gomilu struktura i funkcija a mi bismo željeli imati “nešto” kao: File, BinaryFile, TextFile, ...

Algoritmi i strukture podataka, 2006/07. 8.4.2007

kao: File, BinaryFile, TextFile, ...

7 / 46

Page 8: Uvod u Objektno Orijentirano Programiranje

Potreba za objektno-orijentiranom paradigmom

stvar nije tako kompletno crna jer ovisi i o “razini” funkcionalnosti ugrađenoj u modul:ugrađenoj u modul:

moduli “niske razine” (npr. U/I funkcije u C-u, funkcije za grafičko iscrtavanje u Windowsima) se svakodnevno (i uspješno) iskorištavaju u projektima dilj ijdiljem svijeta- jasno definirani, s dobrom dokumentacijom i “izglačani” dugotrajnim korištenjem

jesmo li (i koliko) uistinu napredovali od asemblera?jesmo li (i koliko) uistinu napredovali od asemblera?MASM (Microsoft Assembler) ima i varijable, i mogućnost definiranja potprograma i mogućnost kreiranja modulapotprograma i mogućnost kreiranja modulazašto nam je onda uopće C zanimljiv?- jednostavnija sintaksa, i (ipak) moćniji skup osnovnih naredbi

traži se potpuno nova paradigma programiranja“odgovor”: objektno-orijentirana paradigma

Algoritmi i strukture podataka, 2006/07. 8.4.2007

g j j p g

8 / 46

Page 9: Uvod u Objektno Orijentirano Programiranje

Malo povijesti

Simula (1967.)prvi programski jezik sa svojstvima objektno-orijentirane paradigme

ij j i d ji t i l ijnamijenjen izgradnji sustava za simulacijuuveden pojam klase / razreda

Smalltalk (1972.) ( )prvi “pravi” (čisti) objektno-orijentiran programski jezik (“sve je objekt”)razvijen u laboratoriju Xerox PARC Smalltalk-80 je najkorištenija verzijaSmalltalk 80 je najkorištenija verzija

C++“hibridni” objektno-orijentirani jezik nastao iz C-a - ispočetka se zvao “C s razredima” (“C with Classes”)with Classes )razvio ga je Bjarne Stroustrup (1983.) u Bell Labsinicijalna ANSI standardizacija je dovršena (tek) 1998., a 2003. je izdana verzija standardna s ispravljenim pogreškamastandardna s ispravljenim pogreškamatrenutno se radi na razvoju novog standarda C++0xC++ je “predak” danas široko korištenih jezika - Java, C# i VB.NET

Algoritmi i strukture podataka, 2006/07. 8.4.2007 9 / 46

Page 10: Uvod u Objektno Orijentirano Programiranje

Kako ćemo “savladati” OOP?

krećemo od (jednostavnog) problema koji ćemo riješiti u C-uidentificirat ćemo nedostatke tog rješenja i kroz postupno uvođenje identificirat ćemo nedostatke tog rješenja i kroz postupno uvođenje koncepata OO paradigme vidjeti kako se oni mogu riješiti u C++ implementacijiimplementacijiproblem:

zadana je datoteka u kojoj se nalazi određeni (nepoznat) broj podataka (radi jednostavnosti, datoteka je slijedna formatirana i sadrži u svakom retku samo jedan podatak tipa int)retku samo jedan podatak tipa int)treba napisati program koji će učitati podatke iz datoteke u memoriju (u strukturu polja nakon učitavanja možemo dohvatiti podatke po indeksu) i strukturu polja – nakon učitavanja možemo dohvatiti podatke po indeksu) i omogućiti njihovu obradu- s obzirom da podaci moraju ostati u memoriji nakon učitavanja, nije moguće

Algoritmi i strukture podataka, 2006/07. 8.4.2007

p j j j , j gjednostavno rješenje slijednog čitanja podataka (jedan po jedan) sve do kraja datoteke!

10 / 46

Page 11: Uvod u Objektno Orijentirano Programiranje

Jednostavno rješenje u C-u

rješenje:pročitamo sve podatke iz datoteke u jednom prolazu radi utvrđivanja koliko pročitamo sve podatke iz datoteke u jednom prolazu radi utvrđivanja koliko ih ukupno imazatim alociramo polje potrebne veličine pomoću malloczatim alociramo polje potrebne veličine pomoću mallocponovno prolazimo kroz datoteku i iznova učitavamo podatke (s time da ih sada spremamo u alocirano polje)sada spremamo u alocirano polje)

ne zadovoljava zadani uvjet!!!primjenjivo kada učinkovitost programa (vrijeme izvršavanja) nije primjenjivo kada učinkovitost programa (vrijeme izvršavanja) nije problem

Algoritmi i strukture podataka, 2006/07. 8.4.2007 11 / 46

Page 12: Uvod u Objektno Orijentirano Programiranje

Bolje rješenje

možemo koristiti funkciju reallocalociramo inicijalni blok memorije (npr za 100 podataka) i zatim ga po alociramo inicijalni blok memorije (npr. za 100 podataka) i zatim ga po potrebi povećavamo tijekom učitavanja

sada imamo 2 veličine koje “opisuju” učitane podatkesada imamo 2 veličine koje opisuju učitane podatkepokazivač na alociranu memorijukoličinu alocirane memorijekoličinu alocirane memorije

dobro je “povezati” podatke – definiramo strukturustruct DinamickoPolje{

int *Podaci;int BrojElem;

};

Algoritmi i strukture podataka, 2006/07. 8.4.2007

};

12 / 46

Page 13: Uvod u Objektno Orijentirano Programiranje

Još bolje rješenje

definiramo i određeni skup funkcija koje će raditi s tom strukturomklasični C idiom klasični C-idiom - struct FILE <=> (fopen, fscanf, fread, ...)

funkcije za DinamickoPolje:funkcije za DinamickoPolje:

int Inicijaliziraj (struct DinamickoPolje *Polje,j j j jint InicijalniBrojElem);

void Izbrisi (struct DinamickoPolje *Polje);int PostaviNovuVelicinu (struct DinamickoPolje *Polje,int PostaviNovuVelicinu (struct DinamickoPolje Polje,

int NoviBrojEl);

P01 DinamickoPolje C osnovna impl

Algoritmi i strukture podataka, 2006/07. 8.4.2007

P01_DinamickoPolje_C_osnovna_impl

13 / 46

Page 14: Uvod u Objektno Orijentirano Programiranje

Što nije dobro?

tehnički nedostaci implementacije u C-u:sami moramo paziti na iskorištenost prostora (BrojUcitanih)sami moramo paziti na iskorištenost prostora (BrojUcitanih)- problem je što je ova struktura samo vrlo jednostavan “omotač” (engl. wrapper) oko

pokazivača („sakrili“ smo malloc i realloc od korisnika strukture, ali nismo definirali nikakvo dodatno ponašanje)

pristup podacima ide preko izravnog korištenja pokazivača koji je dio strukture (P lj P d i[])strukture (Polje.Podaci[])- nameće se primjenjivanje idioma get/set za dohvaćanje i postavljanje vrijednosti

elemenata u poljuelemenata u polju

poboljšanja:u strukturu dodajemo i podatak o iskorištenosti alociranog prostorau strukturu dodajemo i podatak o iskorištenosti alociranog prostoradefiniramo dodatne funkcije za rad sa strukturom

Algoritmi i strukture podataka, 2006/07. 8.4.2007 14 / 46

Page 15: Uvod u Objektno Orijentirano Programiranje

Primjerstruct DinamickoPolje{

int *Podaci;int BrojElem; // koliko stvarno ima elemenata u poljuint BrojElem; // koliko stvarno ima elemenata u poljuint MaxBrojElemenata; // koliki je maksimalno raspolozivi

prostor};

int Inicijaliziraj (struct DinamickoPolje *Polje,int MaxBrojElem);

void Izbrisi (struct DinamickoPolje *Polje);

int PostaviNovuVelicinu (struct DinamickoPolje *Polje, int NoviBrojElem);

id P t iEl t ( t t Di i k P lj *P lj i t I dvoid PostaviElement (struct DinamickoPolje *Polje, int Ind, int Vrijednost);

int DodajElementNaKraj (struct DinamickoPolje *Polje, int Vrijednost);

int DohvatiElement (struct DinamickoPolje *Polje, int Indeks);

int BrojElemenata (struct DinamickoPolje *Polje);

8.4.2007 15 / 46Algoritmi i strukture podataka, 2006/07.

Page 16: Uvod u Objektno Orijentirano Programiranje

Tehnički problem!

funkciju DohvatiElement() smo deklarirali kaoint DohvatiElement (struct DinamickoPolje *Polje, int Indeks);

a što ako se zatraži vrijednost elementa polja za nepostojeći indeks?treba nekako naznačiti pogrešku!

int DohvatiElement (struct DinamickoPolje Polje, int Indeks);

treba nekako naznačiti pogrešku!standardni način u C-u je signaliziranje pogreške preko povratnog argumenta funkcije

novi prototip:

int DohvatiElement2 (struct DinamickoPolje *Polje, int Indeks, int *DohvacenaVrijednost);

preko povratnog parametra (return) signaliziramo pogrešku (ako je bude)preko call by reference vraćamo dohvaćenu vrijednost

int DohvacenaVrijednost);

p y jalternativa: pozvati exit() pa neka programer koji koristi DinamickoPolje popravi pogrešku u svom kodu

P02_DinamickoPolje_C_get_set

8.4.2007 16 / 46Algoritmi i strukture podataka, 2006/07.

Page 17: Uvod u Objektno Orijentirano Programiranje

Ozbiljan nedostatak!

naše DinamickoPolje se može iskoristiti samo za podatke tipa int!p

što ako imamo datoteku u kojoj su zapisani podaci tipa float?kako poopćiti našu implementaciju strukture DinamickoPoljea o poopć t ašu p e e tac ju st u tu e a c o o jeda se može iskoristiti za bilo koji tip podatka?

klasično rješenje u C-u – korištenje typedefj j j ypbolje (i složenije) rješenje – koristimo void * kao tip podataka u polju- programer kod iskorištavanja dinamičkog polja mora koristiti cast operatore!

Naputak: u C++ se učinkovito i programski “čisto” rješava pomoću predložaka (template)

.NET i Java – pojam genericsP03_DinamickoPolje_C_typedef

P03_DinamickoPolje_C_void

8.4.2007 17 / 46Algoritmi i strukture podataka, 2006/07.

Page 18: Uvod u Objektno Orijentirano Programiranje

Nedostaci sa stajališta dizajna programa

svakoj funkciji moramo prenositi pokazivač na strukturuovo je primarno sintaksni “nedostatak”ovo je primarno sintaksni nedostatakprogrameri u C-u (ali i Pascalu, Fortranu, Basicu) s takvom paradigmom “žive” već 20-ak godina ☺žive već 20 ak godina ☺

pozivi funkcija iz biblioteke su isprepleteni s pozivima drugih funkcija i sintaksno izgledaju isto i sintaksno izgledaju isto

smanjuje se razumljivost programa i i i l d idlji ti d kl i nema izravne i na prvi pogled vidljive povezanosti deklarirane

strukture i funkcija koje nad njom operirajusve dobivaju pokazivač struct DinamickoPolje *, ali će korisnici i sami definirati mnoge funkcije koje dobivaju takav pokazivač!

8.4.2007 18 / 46Algoritmi i strukture podataka, 2006/07.

Page 19: Uvod u Objektno Orijentirano Programiranje

Nedostaci – dio drugi

mogućnost sukoba imena (engl. name clash)što ako je u nekoj drugoj biblioteci definirana funkcija s istim imenom?što ako je u nekoj drugoj biblioteci definirana funkcija s istim imenom?koristimo hrvatske nazive za varijable i funkcije pa i nije toliki problem!

kod korištenja engleskih termina (kod izrade biblioteka funkcija bitan zahtjev ako se želi - kod korištenja engleskih termina (kod izrade biblioteka funkcija bitan zahtjev ako se želi omogućiti široko/internacionalno korištenje razvijene biblioteke) je situacija značajno gora (funkcije: initialize, setSize, cleanup ili delete )

što ako netko izravno promijeni vrijednost podatka u strukturi?definirane funkcije se oslanjaju na činjenicu da samo one izravno operiraju nad podacima u strukturi- situacija: korisnik izravno promijeni podatak BrojElem

podaci u polju se nisu promijenili ali će se funkcije drugačije ponašatipodaci u polju se nisu promijenili ali će se funkcije drugačije ponašati

- čak i ako u dokumentaciji eksplicitno piše da se to ne smije raditi, prije ili kasnije će netko to i napraviti (greškom, neznanjem, lijenošću – tako mu je “lakše”)

8.4.2007 19 / 46Algoritmi i strukture podataka, 2006/07.

Page 20: Uvod u Objektno Orijentirano Programiranje

Kako riješiti nedostatke? Jedan po jedan!

uvodimo pojam članske funkcije!u C u (i ostalim proceduralnim jezicima) podaci i funkcije su u programu u C-u (i ostalim proceduralnim jezicima) podaci i funkcije su u programu odvojeninije problem samo po sebi osim u slučajevima koji su slični našem!nije problem samo po sebi, osim u slučajevima koji su slični našem!- funkcije koje smo definirali za rad sa strukturom DinamickoPolje su “intimno”

povezane s tom strukturom- pitanje je kako dodatno naznačiti tu povezanost!

sintaksno – deklaraciju funkcije stavljamo unutar deklaracije strukture

time funkcija postaje “član” struktureterminološka promjena

element strukture (varijabla deklarirana kao dio strukture) postaje članska ( j ) p jvarijabla strukture

8.4.2007 20 / 46Algoritmi i strukture podataka, 2006/07.

Page 21: Uvod u Objektno Orijentirano Programiranje

Jednostavan primjer

struct StrukturaC {int NekiPodatak;

struct StrukturaCPP {int NekiPodatak;int NekiPodatak;

};void Funkcija(StrukturaC *s){ }

int NekiPodatak;

void Funkcija() { }}} };

int main(int argc, char* argv[])int main(int argc, char argv[]) {

StrukturaC objC;Funkcija (&objC);

StrukturaCPP objCPP;objCPP.Funkcija();

return 0;}

P04_PrimjerClanskeFunkcije8.4.2007 21 / 46Algoritmi i strukture podataka, 2006/07.

Page 22: Uvod u Objektno Orijentirano Programiranje

Što smo postigli?

riješili smo “problem” stalnog prenošenja pokazivača na strukturu kao parametrap

“problem” je samo prividno riješen – sada se mora naznačiti za koju varijablu (instancu strukture) se poziva funkcija

riješili smo problem sukoba imenamožemo imati funkcije istog imena, sve dok su one elementi različitih strukturai f k ij k j “di ” t kt i t k j lik j d i poziv funkcija koje su “dio” strukture se sintaksno jasno razlikuju od poziva

“običnih” funkcijakoristimo drugačiji način pozivanjakoristimo drugačiji način pozivanjainstanca_strukture.ime_funkcije(parametri)

funkcije koje izravno djeluju nad podacima u strukturi imaju izravnu vezu s u c je oje a o dje uju ad podac a u s u u aju a u e u skonceptom strukture

jasno, jer su njen integralni dio

8.4.2007 22 / 46Algoritmi i strukture podataka, 2006/07.

Page 23: Uvod u Objektno Orijentirano Programiranje

A kamo je nestalo DinamickoPolje *?

odnosno, kako pozvana funkcija “zna” za koju je varijablu strukture pozvana?funkciji se implicitno prenosi pokazivač this j p p p

this je pokazivač koji pokazuje na varijablu strukture za koju je članska funkcija pozvana“lokalna varijabla” za čiju se “deklaraciju” i inicijalizaciju brine prevodilaclokalna varijabla za čiju se deklaraciju i inicijalizaciju brine prevodilac

Primjer:

int DinamickoPolje::Inicijaliziraj(int inMaxBrojElem) {// implicitno korištenje this_BrojElem = 0;_

// ili eksplicitnothis->_BrojElem = 0;...

}

P04_DinamickoPolje_Cpp1_clanske_funkcije8.4.2007 23 / 46Algoritmi i strukture podataka, 2006/07.

Page 24: Uvod u Objektno Orijentirano Programiranje

Operator određivanja dosega (scope resolution)

pojavile su se neke dvotočke u prethodnom primjeru?

= operator određivanja dosega (scope resolution operator)

int DinamickoPolje::Inicijaliziraj(int inMaxBrojElem)...

:: = operator određivanja dosega (scope resolution operator)u C++: doseg (scope) = “mjera” vidljivosti identifikatora (varijable, funkcije, klase) u programuu našem primjeru je bitan jer njime kod implementacije funkcije j j j j j jInicijaliziraj (a i svake druge članske funkcije) naznačavamo njenu pripadnost razredu DinamickoPolje!

8.4.2007 24 / 46Algoritmi i strukture podataka, 2006/07.

Page 25: Uvod u Objektno Orijentirano Programiranje

Što je ostalo?

i dalje imamo problem – moguće je izravno promijeniti sadržaj varijabli u strukturi

utječemo na kasnije ponašanje članskih funkcija (najčešće s nedefiniranim posljedicama!)rješava se uvođenjem prava pristupa

korištenjem ključnih riječi i t i bli graditelj strukture može odrediti koji njen korištenjem ključnih riječi private i public graditelj strukture može odrediti koji njen dio će biti dostupan svima, a koji dio će biti dostupan samo članskim funkcijama strukture

sintaksa:

struct PrimjerStrukture {public:public:

int _JavnoDostupnaVarijabla;void JavnoDostupnaClanskaFunkcija(int Parametar);

private:private:int _PrivatnaVarijabla;float PrivatnaClanskaFunkcija();

};};

8.4.2007 25 / 46Algoritmi i strukture podataka, 2006/07.

Page 26: Uvod u Objektno Orijentirano Programiranje

Pristup privatnim dijelovima strukture

što se misli pod “dostupan”?može se ograničiti skup mjesta (lokacija) u programu s kojih se može može se ograničiti skup mjesta (lokacija) u programu s kojih se može pristupiti privatnim dijelovima strukture

PrimjerStrukture var;

prevodilac će kod prevođenja programa javiti pogrešku!

PrimjerStrukture var; var._PrivatnaVarijabla = 0;

- prevodilac će kod prevođenja programa javiti pogrešku!

privatnim dijelovima strukture se može pristupiti samo unutar definicije (tijela) članske funkcijedefinicije (tijela) članske funkcije

i članske funkcije mogu biti privatne!napomena: P05 PrimjerStrukturePravaPristupanapomena:

postoji i protected pravo pristupa važno je samo kod uspostavljanja hijerarhije struktura putem nasljeđivanja

_ j p

važno je samo kod uspostavljanja hijerarhije struktura putem nasljeđivanja

8.4.2007 26 / 46Algoritmi i strukture podataka, 2006/07.

Page 27: Uvod u Objektno Orijentirano Programiranje

Konačno – razredi (klase)!

uvodimo ključnu riječ classklasa (razred) poopćava pojam strukture iz C aklasa (razred) poopćava pojam strukture iz C-a

koja je razlika? t išt C dit lj i i t k k d t kt j sa stanovišta C++ prevoditelja primarno sintaksna – kod strukture je sve

podrazumijevano public dok je kod razreda sve podrazumijevano privateprivate

konceptualna razlika:- struktura je (ipak) namijenjena modeliranju skupa jednostavnih podataka nad kojima - struktura je (ipak) namijenjena modeliranju skupa jednostavnih podataka nad kojima

ostali dijelovi programa direktno operiraju- razred kao primarni koncept OO paradigme (prisutan u svim OO jezicima!) namijenjen

j d li j ( d t lj j ) k t i d čj bl k ji j š je modeliranju (predstavljanju) koncepata iz područja problema koji rješavamo (DinamickoPolje, Stog, HashFile, ...) koji imaju složeno ponašanje realizirano preko skupa članskih funkcija

P05_DinamickoPolje_Cpp2_prava_pristupa8.4.2007 27 / 46Algoritmi i strukture podataka, 2006/07.

Page 28: Uvod u Objektno Orijentirano Programiranje

Malo teorije

dva osnovna elementa OO paradigme: apstrakcija i enkapsulacijaapstrakcija razredi / objekti predstavljaju koncepte iz domene apstrakcija – razredi / objekti predstavljaju koncepte iz domene problema koji rješavamo

d Di i k P lj j t k ij k t di ičk lj razred DinamickoPolje je apstrakcija koncepta dinamičkog polja s dobro definiranim karakteristikamanije li to isto i struktura u C u?nije li to isto i struktura u C-u?- struktura predstavlja agregatni skup podataka nad kojima operiraju “vanjski” elementi

programa (funkcije)p g ( j )- vanjske funkcije nisu dio strukture – zbog toga struktura nije “potpuna” jer je za

razumijevanje koncepta koji predstavlja potrebno proučiti nešto što nije dio same definicije strukturedefinicije strukture

- struktura nije “zatvorena” u smislu da ne upravlja sama svojim ponašanjem i stanjem!modeliranjem koncepta pomoću razreda rješavamo navedene problememodeliranjem koncepta pomoću razreda rješavamo navedene probleme

8.4.2007 28 / 46Algoritmi i strukture podataka, 2006/07.

Page 29: Uvod u Objektno Orijentirano Programiranje

Enkapsulacija

niti jedan dio sustava ne bi smio ovisiti o unutrašnjim detaljima drugog dijeladrugog dijela

korisnika razreda DinamickoPolje ne bi trebalo zanimati kako je realizirana njegova funkcionalnost realizirana njegova funkcionalnost - napomena: koncept dinamičkog polja je vrlo jednostavan i praktički implicira način

implementacije (dinamička alokacija memorije za elemente polja), ali kod složenijih d t i k j l č j ij t k !razreda to ni u kojem slučaju nije tako!čak i kod dinamičkog polja možemo imati varijabilnost u implementacijinpr., ako je rukovanje memorijom “skriveno” od korisnika razreda, može se izgraditi l i i ( k i i i ć l ivlastiti memory-manager (ne koristimo malloc i realloc, već vlastitu

implementaciju – npr. radi efikasnosti)

postižemo deklariranjem unutrašnjih detalja razreda kao privatepos e o de a a je u u aš j de a ja a eda ao p atebudući da tada ionako ne može pristupiti tim dijelovima, korisnik razreda DinamickoPolje ne može o njima ni ovisiti (zato jer ih ne može j j ( jizravno referencirati u programskom kodu koji on piše)

8.4.2007 29 / 46Algoritmi i strukture podataka, 2006/07.

Page 30: Uvod u Objektno Orijentirano Programiranje

Javno sučelje razreda

sve što je u razredu deklarirano kao public dio je javnog sučeljajavno sučelje razreda predstavlja “prozor u svijet” kroz koji razred javno sučelje razreda predstavlja “prozor u svijet” kroz koji razred komunicira s ostalim dijelovima programa

d fi i j čl kih ij bli k i t d “ k i ” j t jdefiniranjem članskih varijabli kao private, razred “skriva” svoje stanjeprimjer enkapsulacije u stvarnom životu:

DVD player – javno sučelje čini par kabela i daljinski upravljač- “običnog” korisnika u biti ne zanima kako DVD player radi sve dok on ispravno reagira

na “poruke” zadane preko sučelja (Play Stop Eject )na poruke zadane preko sučelja (Play, Stop, Eject, ... )

slično vrijedi i za razrede k i ik d Di i k P lj bit j d d i za korisnika razreda DinamickoPolje bitno je da razred ima

očekivano ponašanje, a kako je unutar razreda omogućeno takvo ponašanje korisnika (uglavnom) ne zanima!ponašanje, korisnika (uglavnom) ne zanima!

8.4.2007 30 / 46Algoritmi i strukture podataka, 2006/07.

Page 31: Uvod u Objektno Orijentirano Programiranje

Pojam objekta

ovo je deklaracija razreda (novi tip podatka):

class MojRazred {class MojRazred {...

};

slično kao i kod struktura, razred predstavlja predložak iz kojega će se kreirati objekti!obje t

kod struktura koristimo termin varijabla strukture ili instanca strukture kod razreda se konkretna instanca naziva objektom

d j j d i j ž i t i ti i lj b j bj k trazred je jedan, a iz njega se može instancirati proizvoljan broj objekata- svi će biti “isti” u smislu da svi imaju isti skup članskih varijabli i članskih funkcija- objekti se razlikuju po vrijednostima koje imaju njihove članske varijable (te vrijednosti

d t lj j t j bj kt )predstavljaju stanje objekta)- analogija sa strukturom polje – svi članovi su istog tipa, a vrijednosti im se razlikuju za svaki

indeks polja

8.4.2007 31 / 46Algoritmi i strukture podataka, 2006/07.

Page 32: Uvod u Objektno Orijentirano Programiranje

Kreiranje objekata

slično kao i kod struktura, kreiranje objekta primarno podrazumijeva alociranje prostora u memoriji gdje će objekt biti smještenalociranje prostora u memoriji gdje će objekt biti smješten

odnosno, treba alocirati prostor za članske varijable razredamoguća su dva standardna načina:moguća su dva standardna načina:

smještanje objekta na stog bj kt d kl i k l k l i bj kt t f k ij- objekt se deklarira kao lokalni objekt unutar funkcije

smještanje objekta na gomilu (heap) “životni vijek” objekta nije vezan uz kontekst izvođenja funkcije već se objekt - životni vijek objekta nije vezan uz kontekst izvođenja funkcije već se objekt eksplicitno mora “uništiti” (izbrisati iz memorije)

za potrebe rada s objektima na heapu, uvode se operatori:za potrebe rada s objektima na heapu, uvode se operatori:new – operator za kreiranje objekata na heapudelete – operator za brisanje objekata s heapadelete operator za brisanje objekata s heapa

8.4.2007 32 / 46Algoritmi i strukture podataka, 2006/07.

Page 33: Uvod u Objektno Orijentirano Programiranje

Primjer za new i delete

class MojRazred {{public:

int _MojPodatak;};

int main(int argc, char* argv[]) {MojRazred objStog; // objekt na stoguobjStog MojPodatak = 10;objStog._MojPodatak = 10;

MojRazred *pStog = new MojRazred(); // objekt na heapupStog->_MojPodatak = 10;

delete pStog; // moramo eksplicitno osloboditi memoriju

return 0;return 0;// po završetku funkcije, objStog će se automatski // ukloniti iz memorije

}

8.4.2007 33 / 46Algoritmi i strukture podataka, 2006/07.

Page 34: Uvod u Objektno Orijentirano Programiranje

Brisanje polja

new i delete nisu namijenjeni isključivo za kreiranje i uništavanje objekata:predstavljaju općenitu zamjenu za malloc i realloctype safe verzija – točno se zna za kakav tip podatka se alocira memorija

primjeri:float *pFloat = new float;int *pInt = new int[10];char *pString = new char[20];p g [ ];

delete pFloat;delete [] pInt;

za brisanje polja mora se koristiti operator delete []

delete [] pString;

j p j p []

P06_Primjer_new_delete8.4.2007 34 / 46Algoritmi i strukture podataka, 2006/07.

Page 35: Uvod u Objektno Orijentirano Programiranje

Inicijalizacija objekta

kreiranje objekta ipak ne znači samo alokaciju memorije za smještanje objektabitno je u kakvom stanju se objekt nalazi nakon kreiranja, odnosno kakve su mu vrijednosti j j j j , jčlanskih varijabli problem inicijalizacije

javlja se i u C-u:nakon deklaracije int a; nije jednoznačno definirano kakvu vrijednost ima varijabla a

k d bj k t j t l l ž ij j ( j j t ) i j iš čl kih ij blikod objekata je stvar malo složenija jer (vjerojatno) imaju više članskih varijablikako inicijalizirati pokazivače koji su dio razreda?

rješavanju ovog “problema” kod razreda DinamickoPolje namijenjena je rješavanju ovog problema kod razreda DinamickoPolje namijenjena je funkcija Inicijaliziraj() koja dovodi kreirani objekt u ispravno stanje

a što ako kreiramo objekt i zaboravimo pozvati Inicijaliziraj()?j p j j()

pogreška pri korištenju objekta!

8.4.2007 35 / 46Algoritmi i strukture podataka, 2006/07.

Page 36: Uvod u Objektno Orijentirano Programiranje

Pojam konstruktora objekta/razreda

uvodimo pojam konstruktora objektaposebna članska funkcija namijenjena inicijalizaciji stanja objekta kod njegovog kreiranjaprepoznaje se po imenu funkcije – mora biti isto kao i ime razreda

sintaksa:class MojaKlasa {class MojaKlasa {public:

MojaKlasa() { ... } // konstruktor bez parametaraMojaKlasa(int a) { } // konstruktor s parametrom

Primjer preopterećenja (overloadinga) funkcije

MojaKlasa(int a) { ... } // konstruktor s parametrom};

j p p j ( g ) jimamo funkcije istog imena (u C-u nije dozvoljeno) a prevodilac ih razlikuje po parametrima

konstruktor nema povratnog parametra – ne vraća i ne može vratiti nikakav d t k k i š jpodatak nakon izvršavanja

a ako dođe do pogreške koju treba signalizirati ostatku programa – treba “baciti” izuzetak (engl. exception)( g p )

8.4.2007 36 / 46Algoritmi i strukture podataka, 2006/07.

Page 37: Uvod u Objektno Orijentirano Programiranje

Podrazumijevani konstruktor

Primjer korištenja:void main() {void main() {MojaKlasa a;MojaKlasa b(10);M j Kl * M j Kl ()MojaKlasa *c = new MojaKlasa();MojaKlasa *d = new MojaKlasa(10);

}

a kako su onda radili naši prethodni primjeri (bez definiranog konstruktora)?konstruktora)?prevodilac za svaki razred za koji nije eksplicitno definiran konstruktor sam dodaje podrazumijevani (engl default) konstruktorkonstruktor sam dodaje podrazumijevani (engl. default) konstruktor

konstruktor bez parametara koji članske varijable inicijalizira na neke podrazumijevane vrijednostipodrazumijevane vrijednosti

8.4.2007 37 / 46Algoritmi i strukture podataka, 2006/07.

Page 38: Uvod u Objektno Orijentirano Programiranje

Destruktori

definiranjem konstruktora smo “pokrili” kreiranje objekta, a što je s brisanjem (uništavanjem)?brisanjem (uništavanjem)?možemo definirati destruktor razreda

čl k f k ij k j ć i ti ilik išt j bj ktčlanska funkcija koja će se pozivati prilikom uništavanja objekta“uništavanje” objekta = brisanje objekta iz memorije

tehničkim žargonom – objekt izlazi iz dosega (engl. goes out of scope)za objekte kreirane na stogu – trenutak kada funkcija u kojoj su deklarirani završava i briše sve svoje podatke sa stogaza objekte kreirane na heapu – trenutak kad se nad njima poziva delete

ako je u razredu definiran destruktor, prevodilac će ga automatski pozvati u trenutku uništavanja objekta

8.4.2007 38 / 46Algoritmi i strukture podataka, 2006/07.

Page 39: Uvod u Objektno Orijentirano Programiranje

Primjer sintakse

class MojaKlasa {public:public:

MojaKlasa() { ... } // konstruktor 1MojaKlasa(int a) { ... } // konstruktor 2

//~MojaKlasa() { ... } // destruktor (jedan!)};

void main() {MojaKlasa a;MojaKlasa *b = new MojaKlasa();j j ();... // tijelo funkcijedelete b; // poziva se destruktor za b(eksplicitno)

} // prije samog završetka funkcije (return) se} // prije samog završetka funkcije (return) se // poziva destruktor za a

P06_PrimjerKonstruktorDestruktor

8.4.2007 39 / 46Algoritmi i strukture podataka, 2006/07.

Page 40: Uvod u Objektno Orijentirano Programiranje

Curenje memorije

isto pitanje – kako su radili naši prijašnji primjeri u kojima nije bilo destruktora?uništavanje objekta je podrazumijevalo samo oslobađanje memorije (alocirane za smještaj samog objekta) i to za to se pobrinuo prevodilacdestruktor je “glumila” funkcija Izbrisi() koja je oslobađala zauzetu memoriju

a što da smo je zaboravili pozvati?a što da smo je zaboravili pozvati?Imamo curenje memorije (memory leak) u programu – zauzeli smo resurse računala ali ih nismo oslobodili iako ih više ne koristimo“ b t” t k i l č j i ž diti i it d i “zaboravnost” programera u takvim slučajevima može voditi izrazito nezgodnim pogreškama

prednost destruktora – prevodilac će se pobrinuti da se pozove funkcija za p p p p juništavanje objekta

nakon što definiramo destruktor, sigurni smo vrijedi samo za objekte kreirane na stogu kod objekata kreiranih na heapu (pomoću vrijedi samo za objekte kreirane na stogu - kod objekata kreiranih na heapu (pomoću new) mora se pozvati delete!

- kreator objekta određuje kada će se on uništiti

P06_DinamickoPolje_Cpp3_konstruktori

8.4.2007 40 / 46Algoritmi i strukture podataka, 2006/07.

Page 41: Uvod u Objektno Orijentirano Programiranje

Kopiranje objekata

što je s kopiranjem objekata?npr poziv funkcije u koju se po call by value prenosi objektnpr. poziv funkcije u koju se po call by value prenosi objekt

za obične tipove (int, float, char) je to jednostavno – u funkciji se kreira lokalna varijabla istog tipa i (automatski) inicijalizira s prenesenom j g p ( ) j pvrijednošću

a što ako se prenosi objekt?

void NekaFunkcija(MojaKlasa obj) {...

}void main() {MojaKlasa a;

NekaFunkcija(a);}

8.4.2007 41 / 46Algoritmi i strukture podataka, 2006/07.

Page 42: Uvod u Objektno Orijentirano Programiranje

Sintaksa copy-constructora

osnovno pitanje – pomoću kojeg konstruktora se kreira lokalni objekt objprilikom poziva funkcije NekaFunkcija()?poziva se tzv. copy-constructor

a gdje je on u našem razredu? – nema ga eksplicitno, ali je prevodilac sam definirao “standardnu” (default) verzijustandardnu (default) verziju

Sintaksa:class MojaKlasa {class MojaKlasa {public:MojaKlasa() { ... } // konstruktor 1MojaKlasa(int a) { ... } // konstruktor 2M j Kl ( t M j Kl i itObj) { } // t tMojaKlasa(const MojaKlasa &initObj) { ... } // copy-constructor~MojaKlasa() {} // destruktor

};

copy-constructor se prepoznaje po svom parametru – prima referencu na objekt istog tipa koji će poslužiti kao osnova za kreiranje novog objekta

referenca = sakriveni pokazivač (detalji uskoro)referenca = sakriveni pokazivač (detalji uskoro)

8.4.2007 42 / 46Algoritmi i strukture podataka, 2006/07.

Page 43: Uvod u Objektno Orijentirano Programiranje

Problem s copy-constructorom

podrazumijevana implementacija copy-constructora radi samo kopiranje vrijednosti članskih varijabli iz predanog objekta u instancu kopiranje vrijednosti članskih varijabli iz predanog objekta u instancu novostvorenog objektaispravan pristup za jednostavne objekteispravan pristup za jednostavne objekte

objekti koji u sebi nemaju pokazivače na alocirane resurse (memorija, datoteke konekcije na bazu )datoteke, konekcije na bazu, ...)

neispravan za naš razred DinamickoPoljeobjekt kreiran pomoću podrazumijevanog copy-construktora će pokazivati na istu memoriju alociranu za poljenije li to ono što želimo kad Di i k P lj predajemo u funkciju?nije li to ono što želimo kad DinamickoPolje predajemo u funkciju?- NE! – od početka se radi o call by value!

ako želimo da funkcija radi s istom instancom objekta u funkciju se prenosi se - ako želimo da funkcija radi s istom instancom objekta, u funkciju se prenosi se pokazivač na objekt

8.4.2007 43 / 46Algoritmi i strukture podataka, 2006/07.

Page 44: Uvod u Objektno Orijentirano Programiranje

Dva načina kopiranja objekata

postoje dva načina kopiranja objekatadeep copy copy constructor se implementira tako da kreira u potpunosti deep copy – copy-constructor se implementira tako da kreira u potpunosti novu kopiju objekta- za razred DinamickoPolje to znači alociranje nove memorije i inicijalizaciju j j j j j

elemenata u tom polju s vrijednostima iz objekta predanog copy-constructorushallow copy – kreira se novi objekt, ali on nastavlja “dijeliti” određeni dio stanja s objektom na temelju kojega je nastao- za DinamickoPolje to znači da nakon kreiranja objekta pomoću copy-

constructora imamo dva objekta koji pokazuju na istu alociranu memoriju (polje)constructora imamo dva objekta koji pokazuju na istu alociranu memoriju (polje)- doći će do problema kad se pozovu destruktori za ta dva objekta

prvi poziv destruktora će proći u redu, ali kad se pozove destruktor za drugi objekt, k š j l b đ j ć l b đ ij ć k ti škpokušaj oslobađanja već oslobođene memorije će uzrokovati pogrešku

P07_DinamickoPolje_Cpp4_copy_constructor

8.4.2007 44 / 46Algoritmi i strukture podataka, 2006/07.

Page 45: Uvod u Objektno Orijentirano Programiranje

Reference

referenca = pokazivač s malo drugačijom sintaksomnema adresnog operatora i operatora indirekcije (dereferenciranja)nema adresnog operatora i operatora indirekcije (dereferenciranja)

prevodilac to obavlja automatskid kl ij f j fik deklaracija reference se prepoznaje po prefiksu &Primjer: P07_PrimjerReference

void main() {int a = 5;

int *pa = &a; // pokazivač pa pokazuje na varijablu aint &ra = a; // referenca ra također referencira varijablu a

*pa = 10; // varijabla a sada je jednaka 10

ra = 15; // a je sada jednako 15; // j j}

8.4.2007 45 / 46Algoritmi i strukture podataka, 2006/07.

Page 46: Uvod u Objektno Orijentirano Programiranje

Primjeri:

razred Trokut:izgraditi razred Trokut koji će predstavljati koncept trokuta kao izgraditi razred Trokut koji će predstavljati koncept trokuta kao geometrijskog lika koji ima definiranu duljinu svake od tri stranice i ugrađenu funkcionalnost za izračunavanje površine i opsega trokutag j p p g

razred KompleksniBroj:P08_Trokut

razred KompleksniBroj:izgraditi razred KompleksniBroj koji će predstavljati (matematički) koncept kompleksnog broja. Razred mora sadržavati dvije varijable koje će koncept kompleksnog broja. Razred mora sadržavati dvije varijable koje će predstavljati realni i imaginarni dio i pružati funkcionalnost za obavljanje matematičkih operacija s kompleksnim brojevima (zbrajanje, oduzimanje, množenje i dijeljenje)

P09 KompleksniBroj_ p j

8.4.2007 46 / 46Algoritmi i strukture podataka, 2006/07.