You are on page 1of 46

Uvod u objektno-orijentirano

programiranje u programskom
jeziku C++

8.4.2007

autor: dr. sc. Zvonimir Vanjak

Evolucija programskih jezika


prva generacija strojni jezik
druga generacija asembler
trea generacija Pascal, C, Fortran, Algol, LISP, ...
uvodi se paradigma proceduralnog, strukturnog i modularnog programiranja
pojavljuju se i vienamjenski jezici
objektno-orijentirani jezici kao nova paradigma razvoja (
-

Smalltalk, C++, Java, C#

etvrta generacija 4GL jezici


jezici specijalizirani za odreenu domenu problema

Algoritmi i strukture podataka, 2006/07.

8.4.2007

2 / 46

Razvoj tipinog programera


uglavnom zapoinje uenjem nekog programskog jezika tree
generacije
Basic, Pascal, C
sreom uenje strojnog jezika i asemblera je iza nas ()
sreom,

koristi se paradigma nestrukturiranog programiranja


zapoinje
i j se pisanjem
i j malih
lih i jjednostavnih
d t ih programa kkojiji se sastoje
t j odd
slijeda naredbi i djeluju nad zajednikim skupom podataka

Algoritmi i strukture podataka, 2006/07.

8.4.2007

3 / 46

Proceduralna paradigma - I
osnovni korak je uvoenje funkcija koje su izgraene kao skup naredbi i koje imaju dobro
definiran ulaz i izlaz (ve vieno na PIPI-ju)
rjeavamo se problema ponavljanja programskog kda!!!
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

Proceduralna paradigma - II
primjeri:
matematike funkcije sin,
sin cos
funkcije za U/I printf, fwrite
funkcije
j za rad s ggrafikom - DrawLine,, DrawCircle

a to ako je netko ve implementirao takve funkcije?!


moemo ih (j(jednostavno)) iskoristiti!
-

veina razvojnih okruenja dolazi s ugraenom gomilom biblioteka takvih funkcija

reusabilityy mogunost
g
ponovnogg iskoritavanja
j programskog
g
g kda
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

Modularno programiranje
procedure srodne funkcionalnosti grupiraju se u module koji mogu imati vlastite
p
podatke
Program

Modul 1
Podaci 1

Podaci

Procedura 1
Lokalni podaci

Modul 2
P d i1
Podaci

Procedura 2

Procedura 3

Lokalni podaci

Lokalni podaci

Algoritmi i strukture podataka, 2006/07.

8.4.2007

6 / 46

I dalje nije sve idealno!


teko 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 moe biti:
-

.h datoteka s pripadajuom .cpp datotekom


biblioteka funkcija koja se statiki povezuje (linka) u na program
Windows DLL biblioteka

koncept modula je najee implementacijski detalj programskog okruenja u kojem radimo


i nije potpuno integriran u sam programski jezik

osnovni problem je to funkcije i podaci ugraeni u modul nisu povezani u


konkretne programske entitete koji bi predstavljali razumljiv i jasan koncept za
k j j kkorisnike
krajnje
i ik modula
d l
standardni <stdio.h> predstavlja gomilu struktura i funkcija a mi bismo eljeli imati neto
kao: File, BinaryFile, TextFile, ...
Algoritmi i strukture podataka, 2006/07.

8.4.2007

7 / 46

Potreba za objektno-orijentiranom paradigmom


stvar nije tako kompletno crna jer ovisi i o razini funkcionalnosti
ugraenoj u modul:
moduli niske razine (npr. U/I funkcije u C-u, funkcije za grafiko iscrtavanje
u Windowsima) se svakodnevno (i uspjeno) iskoritavaju u projektima
dilj svijeta
diljem
ij
-

jasno definirani, s dobrom dokumentacijom i izglaani dugotrajnim koritenjem

jesmo li (i koliko) uistinu napredovali od asemblera?


MASM (Microsoft Assembler) ima i varijable, i mogunost definiranja
potprograma i mogunost kreiranja modula
zato nam je onda uope C zanimljiv?
-

jednostavnija sintaksa, i (ipak) moniji skup osnovnih naredbi

trai se potpuno nova paradigma programiranja


odgovor:
g
objektno-orijentirana
j
j
pparadigma
g
Algoritmi i strukture podataka, 2006/07.

8.4.2007

8 / 46

Malo povijesti
Simula (1967.)
prvi programski jezik sa svojstvima objektno-orijentirane paradigme
namijenjen
ij j iizgradnji
d ji sustava
t
za simulaciju
i l ij
uveden pojam klase / razreda

Smalltalk (1972.)
(
)
prvi pravi (isti) objektno-orijentiran programski jezik (sve je objekt)
razvijen u laboratoriju Xerox PARC
Smalltalk-80
Smalltalk
80 je najkoritenija verzija

C++
hibridni objektno-orijentirani jezik nastao iz C-a - ispoetka se zvao C s razredima (C
with Classes
Classes))
razvio ga je Bjarne Stroustrup (1983.) u Bell Labs
inicijalna ANSI standardizacija je dovrena (tek) 1998., a 2003. je izdana verzija
standardna s ispravljenim pogrekama
trenutno se radi na razvoju novog standarda C++0x
C++ je predak danas iroko koritenih jezika - Java, C# i VB.NET

Algoritmi i strukture podataka, 2006/07.

8.4.2007

9 / 46

Kako emo savladati OOP?


kreemo od (jednostavnog) problema koji emo rijeiti u C-u
identificirat emo nedostatke tog rjeenja i kroz postupno uvoenje
koncepata OO paradigme vidjeti kako se oni mogu rijeiti u C++
implementaciji
problem:
zadana je datoteka u kojoj se nalazi odreeni (nepoznat) broj podataka
(radi jednostavnosti, datoteka je slijedna formatirana i sadri u svakom
retku samo jedan podatak tipa int)
treba napisati program koji e uitati podatke iz datoteke u memoriju (u
strukturu polja nakon uitavanja moemo dohvatiti podatke po indeksu) i
omoguiti njihovu obradu
-

s obzirom da ppodaci moraju


j ostati u memorijij nakon uitavanja,
j , nije
j mogue
g
jednostavno rjeenje slijednog itanja podataka (jedan po jedan) sve do kraja datoteke!

Algoritmi i strukture podataka, 2006/07.

8.4.2007

10 / 46

Jednostavno rjeenje u C-u


rjeenje:
proitamo sve podatke iz datoteke u jednom prolazu radi utvrivanja koliko
ih ukupno ima
zatim alociramo polje potrebne veliine pomou malloc
ponovno prolazimo kroz datoteku i iznova uitavamo podatke (s time da ih
sada spremamo u alocirano polje)

ne zadovoljava zadani uvjet!!!


primjenjivo kada uinkovitost programa (vrijeme izvravanja) nije
problem

Algoritmi i strukture podataka, 2006/07.

8.4.2007

11 / 46

Bolje rjeenje
moemo koristiti funkciju realloc
alociramo inicijalni blok memorije (npr
(npr. za 100 podataka) i zatim ga po
potrebi poveavamo tijekom uitavanja

sada imamo 2 veliine koje opisuju


opisuju uitane podatke
pokaziva na alociranu memoriju
koliinu alocirane memorije

dobro je povezati podatke definiramo strukturu


struct DinamickoPolje
{
int *Podaci;
int BrojElem;
};
Algoritmi i strukture podataka, 2006/07.

8.4.2007

12 / 46

Jo bolje rjeenje
definiramo i odreeni skup funkcija koje e raditi s tom strukturom
klasini C-idiom
C idiom
-

struct FILE <=> (fopen, fscanf, fread, ...)

funkcije za DinamickoPolje:
int

Inicijaliziraj
j
j (struct DinamickoPolje
j *Polje,
j
int InicijalniBrojElem);
void Izbrisi (struct DinamickoPolje *Polje);
int PostaviNovuVelicinu (struct DinamickoPolje *Polje,
Polje,
int NoviBrojEl);

P01 DinamickoPolje C osnovna impl


P01_DinamickoPolje_C_osnovna_impl
Algoritmi i strukture podataka, 2006/07.

8.4.2007

13 / 46

to nije dobro?
tehniki nedostaci implementacije u C-u:
sami moramo paziti na iskoritenost prostora (BrojUcitanih)
-

problem je to je ova struktura samo vrlo jednostavan omota (engl. wrapper) oko
pokazivaa (sakrili smo malloc i realloc od korisnika strukture, ali nismo
definirali nikakvo dodatno ponaanje)

pristup podacima ide preko izravnog koritenja pokazivaa koji je dio


strukture (Polje.Podaci[])
(P lj P d i[])
-

namee se primjenjivanje idioma get/set za dohvaanje i postavljanje vrijednosti


elemenata u polju

poboljanja:
u strukturu dodajemo i podatak o iskoritenosti alociranog prostora
definiramo dodatne funkcije za rad sa strukturom

Algoritmi i strukture podataka, 2006/07.

8.4.2007

14 / 46

Primjer
struct DinamickoPolje
{
int *Podaci;
int BrojElem;
// koliko stvarno ima elemenata u polju
int 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);

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

DodajElementNaKraj (struct DinamickoPolje *Polje,


int Vrijednost);

int

DohvatiElement (struct DinamickoPolje *Polje, int Indeks);

int

BrojElemenata (struct DinamickoPolje *Polje);

Algoritmi i strukture podataka, 2006/07.

8.4.2007

15 / 46

Tehniki problem!
funkciju DohvatiElement() smo deklarirali kao
int

DohvatiElement (struct DinamickoPolje *Polje,


Polje, int Indeks);

a to ako se zatrai vrijednost elementa polja za nepostojei indeks?


treba nekako naznaiti pogreku!

standardni nain u C-u je signaliziranje pogreke preko povratnog argumenta


funkcije
novi prototip:
int DohvatiElement2 (struct DinamickoPolje *Polje, int Indeks,
int *DohvacenaVrijednost);
DohvacenaVrijednost);

preko povratnog parametra (return) signaliziramo pogreku (ako je bude)


ppreko call byy reference vraamo dohvaenu vrijednost
j

alternativa: pozvati exit() pa neka programer koji koristi


DinamickoPolje popravi pogreku u svom kodu
P02_DinamickoPolje_C_get_set
Algoritmi i strukture podataka, 2006/07.

8.4.2007

16 / 46

Ozbiljan nedostatak!
nae DinamickoPolje se moe iskoristiti samo za podatke
tipa
p int!
to ako imamo datoteku u kojoj su zapisani podaci tipa float?

kako
a o poop
poopitit nau
au implementaciju
p e e tac ju st
strukture
u tu e DinamickoPolje
a c o o je
da se moe iskoristiti za bilo koji tip podatka?
klasino rjeenje
j
j u C-u koritenje
j typedef
yp
bolje (i sloenije) rjeenje koristimo void * kao tip podataka u polju
-

programer kod iskoritavanja dinamikog polja mora koristiti cast operatore!

Naputak: u C++ se uinkovito i programski isto rjeava pomou


predloaka (template)
.NET i Java pojam generics
P03_DinamickoPolje_C_typedef
P03_DinamickoPolje_C_void
Algoritmi i strukture podataka, 2006/07.

8.4.2007

17 / 46

Nedostaci sa stajalita dizajna programa


svakoj funkciji moramo prenositi pokaziva na strukturu
ovo je primarno sintaksni nedostatak
nedostatak
programeri u C-u (ali i Pascalu, Fortranu, Basicu) s takvom paradigmom
ive
ive ve 20
20-ak
ak godina

pozivi funkcija iz biblioteke su isprepleteni s pozivima drugih funkcija


i sintaksno izgledaju isto
smanjuje se razumljivost programa

nema iizravne i na prvii pogled


l d vidljive
idlji povezanostiti ddeklarirane
kl i
strukture i funkcija koje nad njom operiraju
sve dobivaju pokaziva struct DinamickoPolje *, ali e
korisnici i sami definirati mnoge funkcije koje dobivaju takav pokaziva!
Algoritmi i strukture podataka, 2006/07.

8.4.2007

18 / 46

Nedostaci dio drugi


mogunost sukoba imena (engl. name clash)
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 koritenja engleskih termina (kod izrade biblioteka funkcija bitan zahtjev ako se eli
omoguiti iroko/internacionalno koritenje razvijene biblioteke) je situacija znaajno
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 drugaije ponaati

ak i ako u dokumentaciji eksplicitno pie da se to ne smije raditi, prije ili kasnije e


netko to i napraviti (grekom, neznanjem, lijenou tako mu je lake)

Algoritmi i strukture podataka, 2006/07.

8.4.2007

19 / 46

Kako rijeiti nedostatke? Jedan po jedan!


uvodimo pojam lanske funkcije!
u C-u
C u (i ostalim proceduralnim jezicima) podaci i funkcije su u programu
odvojeni
nije problem samo po sebi
sebi, osim u sluajevima koji su slini naem!
-

funkcije koje smo definirali za rad sa strukturom DinamickoPolje su intimno


povezane s tom strukturom
pitanje je kako dodatno naznaiti tu povezanost!

sintaksno deklaraciju funkcije stavljamo unutar deklaracije


strukture
time funkcija postaje lan strukture

terminoloka promjena
element strukture ((varijabla
j
deklarirana kao dio strukture)) ppostaje
j lanska
varijabla strukture
Algoritmi i strukture podataka, 2006/07.

8.4.2007

20 / 46

Jednostavan primjer
struct StrukturaC {
int NekiPodatak;
};
void Funkcija(StrukturaC *s){
}

struct StrukturaCPP {
int NekiPodatak;
void Funkcija() { }
}
};

int main(int argc, char*


char argv[])
{
StrukturaC objC;
Funkcija (&objC);
StrukturaCPP objCPP;
objCPP.Funkcija();
}

return 0;

P04_PrimjerClanskeFunkcije
Algoritmi i strukture podataka, 2006/07.

8.4.2007

21 / 46

to smo postigli?
rijeili smo problem stalnog prenoenja pokazivaa na strukturu kao
p
parametra
problem je samo prividno rijeen sada se mora naznaiti za koju varijablu (instancu
strukture) se poziva funkcija

rijeili smo problem sukoba imena


moemo imati funkcije istog imena, sve dok su one elementi razliitih struktura

poziv
i funkcija
f k ij koje
k j su dio
di strukture
t kt se sintaksno
i t k
jjasno razlikuju
lik j odd poziva
i
obinih funkcija
koristimo drugaiji nain pozivanja
instanca_strukture.ime_funkcije(parametri)

funkcije
u c je koje
oje izravno
a o dje
djeluju
uju nad
ad podac
podacimaa u sstrukturi
u u imaju
aju izravnu
a u vezu
e us
konceptom strukture
jasno, jer su njen integralni dio

Algoritmi i strukture podataka, 2006/07.

8.4.2007

22 / 46

A kamo je nestalo DinamickoPolje *?


odnosno, kako pozvana funkcija zna za koju je varijablu strukture pozvana?
funkcijij se implicitno
p
pprenosi ppokaziva this
this je pokaziva koji pokazuje na varijablu strukture za koju je lanska funkcija
pozvana
lokalna
lokalna varijabla
varijabla za iju se deklaraciju
deklaraciju i inicijalizaciju brine prevodilac

Primjer:
int DinamickoPolje::Inicijaliziraj(int inMaxBrojElem) {
// implicitno koritenje this
_BrojElem = 0;
_

// ili eksplicitno
this->_BrojElem = 0;
...

P04_DinamickoPolje_Cpp1_clanske_funkcije
Algoritmi i strukture podataka, 2006/07.

8.4.2007

23 / 46

Operator odreivanja dosega (scope resolution)


pojavile su se neke dvotoke u prethodnom primjeru?
int DinamickoPolje::Inicijaliziraj(int inMaxBrojElem)...

:: = operator odreivanja dosega (scope resolution operator)


u C++: doseg (scope) = mjera vidljivosti identifikatora (varijable,
funkcije, klase) u programu
u naem primjeru
j je
j bitan jer
j njime
j
kod implementacije
j funkcije
j
Inicijaliziraj (a i svake druge lanske funkcije)
naznaavamo njenu pripadnost razredu DinamickoPolje!

Algoritmi i strukture podataka, 2006/07.

8.4.2007

24 / 46

to je ostalo?
i dalje imamo problem mogue je izravno promijeniti sadraj varijabli u
strukturi
utjeemo na kasnije ponaanje lanskih funkcija (najee s nedefiniranim posljedicama!)

rjeava se uvoenjem prava pristupa


koritenjem kljunih rijei private
i t i public
bli graditelj strukture moe odrediti koji njen
dio e biti dostupan svima, a koji dio e biti dostupan samo lanskim funkcijama strukture

sintaksa:
struct PrimjerStrukture {
public:
int
_JavnoDostupnaVarijabla;
void
JavnoDostupnaClanskaFunkcija(int Parametar);
private:
int
_PrivatnaVarijabla;
float PrivatnaClanskaFunkcija();
};
Algoritmi i strukture podataka, 2006/07.

8.4.2007

25 / 46

Pristup privatnim dijelovima strukture


to se misli pod dostupan?
moe se ograniiti skup mjesta (lokacija) u programu s kojih se moe
pristupiti privatnim dijelovima strukture
PrimjerStrukture var;
var._PrivatnaVarijabla = 0;
-

prevodilac e kod prevoenja programa javiti pogreku!

privatnim dijelovima strukture se moe pristupiti samo unutar


definicije (tijela) lanske funkcije
i lanske funkcije mogu biti privatne!
P05_PrimjerStrukturePravaPristupa
j
p
napomena:
postoji i protected pravo pristupa
vano je samo kod uspostavljanja hijerarhije struktura putem nasljeivanja
Algoritmi i strukture podataka, 2006/07.

8.4.2007

26 / 46

Konano razredi (klase)!


uvodimo kljunu rije class
klasa (razred) poopava pojam strukture iz C-a
Ca

koja je razlika?
sa stanovita
t
it C
C++ prevoditelja
dit lj primarno
i
sintaksna
i t k
kod
k d strukture
t kt jje sve
podrazumijevano public dok je kod razreda sve podrazumijevano
private
konceptualna razlika:
-

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 modeliranju
je
d li j ((predstavljanju)
d t lj j ) kkoncepata
t iiz podruja
d j problema
bl
kkojiji rjeavamo
j
(DinamickoPolje, Stog, HashFile, ...) koji imaju sloeno ponaanje
realizirano preko skupa lanskih funkcija

P05_DinamickoPolje_Cpp2_prava_pristupa
Algoritmi i strukture podataka, 2006/07.

8.4.2007

27 / 46

Malo teorije
dva osnovna elementa OO paradigme: apstrakcija i enkapsulacija
apstrakcija razredi / objekti predstavljaju koncepte iz domene
problema koji rjeavamo
razredd DinamickoPolje
Di
i k P lj je
j apstrakcija
t k ij kkoncepta
t di
dinamikog
ik polja
lj s
dobro definiranim karakteristikama
nije li to isto i struktura u C-u?
C u?
-

struktura predstavlja agregatni skup podataka nad kojima operiraju vanjski elementi
pprograma
g
((funkcije)
j )
vanjske funkcije nisu dio strukture zbog toga struktura nije potpuna jer je za
razumijevanje koncepta koji predstavlja potrebno prouiti neto to nije dio same
definicije strukture
struktura nije zatvorena u smislu da ne upravlja sama svojim ponaanjem i stanjem!

modeliranjem koncepta pomou razreda rjeavamo navedene probleme


Algoritmi i strukture podataka, 2006/07.

8.4.2007

28 / 46

Enkapsulacija
niti jedan dio sustava ne bi smio ovisiti o unutranjim detaljima
drugog dijela
korisnika razreda DinamickoPolje ne bi trebalo zanimati kako je
realizirana njegova funkcionalnost
-

napomena: koncept dinamikog polja je vrlo jednostavan i praktiki implicira nain


implementacije (dinamika alokacija memorije za elemente polja), ali kod sloenijih
razreda
d tto nii u kojem
k j sluaju
l j nije
ij ttako!
k !
ak i kod dinamikog polja moemo imati varijabilnost u implementaciji
npr., ako je rukovanje memorijom skriveno od korisnika razreda, moe se izgraditi
vlastiti
l i i memory-manager (ne
( koristimo
k i i
malloc i realloc, ve vlastitu
l i
implementaciju npr. radi efikasnosti)

postiemo
pos
e o de
deklariranjem
a a je uunutranjih
u a j de
detalja
a ja razreda
a eda kao
ao p
private
ate
budui da tada ionako ne moe pristupiti tim dijelovima, korisnik razreda
DinamickoPolje
j ne moe o njima
j
ni ovisiti ((zato jjer ih ne moe
izravno referencirati u programskom kodu koji on pie)
Algoritmi i strukture podataka, 2006/07.

8.4.2007

29 / 46

Javno suelje razreda


sve to je u razredu deklarirano kao public dio je javnog suelja
javno suelje razreda predstavlja prozor u svijet kroz koji razred
komunicira s ostalim dijelovima programa
d fi i j lanskih
definiranjem
l kih varijabli
ij bli kkao private,
i t razredd skriva
k i svoje
j stanje
t j

primjer enkapsulacije u stvarnom ivotu:


DVD player javno suelje ini par kabela i daljinski upravlja
-

obinog korisnika u biti ne zanima kako DVD player radi sve dok on ispravno reagira
na poruke
poruke zadane preko suelja (Play
(Play, Stop,
Stop Eject,
Eject ... )

slino vrijedi i za razrede


za korisnika
k i ik razreda
d DinamickoPolje
Di
i k P lj bitno
bit jje dda razredd iima
oekivano ponaanje, a kako je unutar razreda omogueno takvo
ponaanje korisnika (uglavnom) ne zanima!
ponaanje,
Algoritmi i strukture podataka, 2006/07.

8.4.2007

30 / 46

Pojam objekta
ovo je deklaracija razreda (novi tip podatka):
class MojRazred {
};

...

slino kao i kod struktura, razred predstavlja predloak iz kojega e se kreirati


obje t
objekti!
kod struktura koristimo termin varijabla strukture ili instanca strukture
kod razreda se konkretna instanca naziva objektom
razredd jje jjedan,
d a iiz njega
j
se moe
iinstancirati
t i ti proizvoljan
i lj bbrojj objekata
bj k t
-

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
predstavljaju
d t lj j stanje
t j objekta)
bj kt )
analogija sa strukturom polje svi lanovi su istog tipa, a vrijednosti im se razlikuju za svaki
indeks polja

Algoritmi i strukture podataka, 2006/07.

8.4.2007

31 / 46

Kreiranje objekata
slino kao i kod struktura, kreiranje objekta primarno podrazumijeva
alociranje prostora u memoriji gdje e objekt biti smjeten
odnosno, treba alocirati prostor za lanske varijable razreda

mogua su dva standardna naina:


smjetanje objekta na stog
-

objekt
bj kt se ddeklarira
kl i kkao llokalni
k l i objekt
bj kt unutar
t ffunkcije
k ij

smjetanje objekta na gomilu (heap)


-

ivotni
ivotni vijek
vijek objekta nije vezan uz kontekst izvoenja funkcije ve se objekt
eksplicitno mora unititi (izbrisati iz memorije)

za potrebe rada s objektima na heapu, uvode se operatori:


new operator za kreiranje objekata na heapu
delete operator za brisanje objekata s heapa
Algoritmi i strukture podataka, 2006/07.

8.4.2007

32 / 46

Primjer za new i delete


class MojRazred
{
public:
int _MojPodatak;
};
int main(int argc, char* argv[]) {
MojRazred objStog;
// objekt na stogu
objStog MojPodatak = 10;
objStog._MojPodatak
MojRazred *pStog = new MojRazred(); // objekt na heapu
pStog->_MojPodatak = 10;
delete pStog; // moramo eksplicitno osloboditi memoriju

return 0;
// po zavretku funkcije, objStog e se automatski
// ukloniti iz memorije

Algoritmi i strukture podataka, 2006/07.

8.4.2007

33 / 46

Brisanje polja
new i delete nisu namijenjeni iskljuivo za kreiranje i unitavanje objekata:
predstavljaju openitu zamjenu za malloc i realloc
type safe verzija tono se zna za kakav tip podatka se alocira memorija

primjeri:
float
int
char

*pFloat = new float;


*pInt = new int[10];
*pString
p
g = new char[20];
[ ];

delete pFloat;
delete [] pInt;
delete [] pString;

za brisanje
j ppolja
j mora se koristiti operator
p
delete []

P06_Primjer_new_delete
Algoritmi i strukture podataka, 2006/07.

8.4.2007

34 / 46

Inicijalizacija objekta
kreiranje objekta ipak ne znai samo alokaciju memorije za smjetanje objekta
bitno jje u kakvom stanju
j se objekt
j nalazi nakon kreiranja,
j , odnosno kakve su mu vrijednosti
j
lanskih varijabli
problem inicijalizacije

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

k d objekata
kod
bj k t jje stvar
t malo
l sloenija
l ij jjer ((vjerojatno)
j j t ) iimaju
j vie
i lanskih
l kih varijabli
ij bli
kako inicijalizirati pokazivae koji su dio razreda?

rjeavanju ovog problema


problema kod razreda DinamickoPolje namijenjena je
funkcija Inicijaliziraj() koja dovodi kreirani objekt u ispravno stanje
a to ako kreiramo objekt
j i zaboravimo ppozvati Inicijaliziraj()?
j
j()
pogreka pri koritenju objekta!

Algoritmi i strukture podataka, 2006/07.

8.4.2007

35 / 46

Pojam konstruktora objekta/razreda


uvodimo pojam konstruktora objekta
posebna lanska funkcija namijenjena inicijalizaciji stanja objekta kod njegovog kreiranja
prepoznaje se po imenu funkcije mora biti isto kao i ime razreda

sintaksa:
class MojaKlasa {
public:
MojaKlasa() { ... } // konstruktor bez parametara
MojaKlasa(int a) { ... } // konstruktor s parametrom
};

Primjer
j preoptereenja
p p
j ((overloadinga)
g ) funkcije
j
imamo funkcije istog imena (u C-u nije dozvoljeno) a prevodilac ih razlikuje po parametrima

konstruktor nema povratnog parametra ne vraa i ne moe vratiti nikakav


podatak
d t k nakon
k iizvravanja

j
a ako doe do pogreke koju treba signalizirati ostatku programa treba baciti izuzetak
((engl.
g exception)
p )
Algoritmi i strukture podataka, 2006/07.

8.4.2007

36 / 46

Podrazumijevani konstruktor
Primjer koritenja:
void main() {
MojaKlasa a;
MojaKlasa b(10);
M j Kl
MojaKlasa
* = new M
*c
MojaKlasa();
j Kl
()
MojaKlasa *d = new MojaKlasa(10);
}

a kako su onda radili nai prethodni primjeri (bez definiranog


konstruktora)?
prevodilac za svaki razred za koji nije eksplicitno definiran
konstruktor sam dodaje podrazumijevani (engl.
(engl default) konstruktor
konstruktor bez parametara koji lanske varijable inicijalizira na neke
podrazumijevane vrijednosti
Algoritmi i strukture podataka, 2006/07.

8.4.2007

37 / 46

Destruktori
definiranjem konstruktora smo pokrili kreiranje objekta, a to je s
brisanjem (unitavanjem)?
moemo definirati destruktor razreda
l k funkcija
lanska
f k ij kkoja
j e
se pozivati
i ti prilikom
ilik unitavanja
it
j objekta
bj kt

unitavanje objekta = brisanje objekta iz memorije


tehnikim argonom objekt izlazi iz dosega (engl. goes out of scope)
za objekte kreirane na stogu trenutak kada funkcija u kojoj su deklarirani
zavrava i brie sve svoje podatke sa stoga
za objekte kreirane na heapu trenutak kad se nad njima poziva delete

ako je u razredu definiran destruktor, prevodilac e ga automatski


pozvati u trenutku unitavanja objekta
Algoritmi i strukture podataka, 2006/07.

8.4.2007

38 / 46

Primjer sintakse
class MojaKlasa {
public:
MojaKlasa() { ... }
// konstruktor 1
MojaKlasa(int a) { ... } // konstruktor 2
~MojaKlasa() { ... }
// destruktor (jedan!)
};
void main() {
MojaKlasa a;
MojaKlasa
j
*b = new MojaKlasa();
j
();
... // tijelo funkcije
delete b; // poziva se destruktor za b(eksplicitno)
}
// prije samog zavretka funkcije (return) se
// poziva destruktor za a

P06_PrimjerKonstruktorDestruktor
Algoritmi i strukture podataka, 2006/07.

8.4.2007

39 / 46

Curenje memorije
isto pitanje kako su radili nai prijanji primjeri u kojima nije bilo destruktora?
unitavanje objekta je podrazumijevalo samo oslobaanje memorije (alocirane za smjetaj
samog objekta) i to za to se pobrinuo prevodilac
destruktor je glumila funkcija Izbrisi() koja je oslobaala zauzetu memoriju

a to da smo je zaboravili pozvati?


Imamo curenje memorije (memory leak) u programu zauzeli smo resurse raunala ali ih
nismo oslobodili iako ih vie ne koristimo
b
zaboravnost
t programera u ttakvim
k i sluajevima
l j i moe
voditi
diti iizrazito
it nezgodnim
d i
pogrekama

p
prednost
destruktora pprevodilac e se ppobrinuti da se ppozove funkcija
j za
unitavanje objekta
nakon to definiramo destruktor, sigurni smo
vrijedi samo za objekte kreirane na stogu - kod objekata kreiranih na heapu (pomou
new) mora se pozvati delete!
-

kreator objekta odreuje kada e se on unititi

P06_DinamickoPolje_Cpp3_konstruktori
Algoritmi i strukture podataka, 2006/07.

8.4.2007

40 / 46

Kopiranje objekata
to je s kopiranjem objekata?
npr poziv funkcije u koju se po call by value prenosi objekt
npr.
za obine tipove (int, float, char) je to jednostavno u funkciji se
kreira lokalna varijabla
j
istogg tipa
p i ((automatski)) inicijalizira
j
s pprenesenom
vrijednou

a to ako se prenosi objekt?


void NekaFunkcija(MojaKlasa obj) {
...
}
void main() {
MojaKlasa a;
}

NekaFunkcija(a);

Algoritmi i strukture podataka, 2006/07.

8.4.2007

41 / 46

Sintaksa copy-constructora
osnovno pitanje pomou kojeg konstruktora se kreira lokalni objekt obj
prilikom poziva funkcije NekaFunkcija()?
poziva se tzv. copy-constructor
a gdje je on u naem razredu? nema ga eksplicitno, ali je prevodilac sam definirao
standardnu (default) verziju
standardnu

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

copy-constructor se prepoznaje po svom parametru prima referencu na


objekt istog tipa koji e posluiti kao osnova za kreiranje novog objekta
referenca = sakriveni pokaziva (detalji uskoro)
Algoritmi i strukture podataka, 2006/07.

8.4.2007

42 / 46

Problem s copy-constructorom
podrazumijevana implementacija copy-constructora radi samo
kopiranje vrijednosti lanskih varijabli iz predanog objekta u instancu
novostvorenog objekta
ispravan pristup za jednostavne objekte
objekti koji u sebi nemaju pokazivae na alocirane resurse (memorija,
datoteke konekcije na bazu
datoteke,
bazu, ...))

neispravan za na razred DinamickoPolje


objekt kreiran pomou podrazumijevanog copy-construktora e pokazivati
na istu memoriju alociranu za polje
nije li to ono to elimo kad DinamickoPolje
Di
i k P lj predajemo u funkciju?
-

NE! od poetka se radi o call by value!


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

Algoritmi i strukture podataka, 2006/07.

8.4.2007

43 / 46

Dva naina kopiranja objekata


postoje dva naina kopiranja objekata
deep copy copy-constructor
copy constructor se implementira tako da kreira u potpunosti
novu kopiju objekta
-

za razred DinamickoPolje
j to znai alociranje
j nove memorije
j i inicijalizaciju
j
j
elemenata u tom polju s vrijednostima iz objekta predanog copy-constructoru

shallow copy kreira se novi objekt, ali on nastavlja dijeliti odreeni dio
stanja s objektom na temelju kojega je nastao
-

za DinamickoPolje to znai da nakon kreiranja objekta pomou copyconstructora imamo dva objekta koji pokazuju na istu alociranu memoriju (polje)
doi e do problema kad se pozovu destruktori za ta dva objekta
prvi poziv destruktora e proi u redu, ali kad se pozove destruktor za drugi objekt,
pokuaj
k j oslobaanja
l b j ve
osloboene
l b
memorije
ij e
uzrokovati
k
ti pogreku
k

P07_DinamickoPolje_Cpp4_copy_constructor
Algoritmi i strukture podataka, 2006/07.

8.4.2007

44 / 46

Reference
referenca = pokaziva s malo drugaijom sintaksom
nema adresnog operatora i operatora indirekcije (dereferenciranja)
prevodilac to obavlja automatski

d kl
deklaracija
ij reference
f
se prepoznaje
j po prefiksu
fik &
Primjer:

P07_PrimjerReference

void main() {
int a = 5;
int *pa = &a;
int &ra = a;
*pa = 10;
ra = 15;
;
}

// pokaziva pa pokazuje na varijablu a


// referenca ra takoer referencira varijablu a

// varijabla a sada je jednaka 10


// a j
je sada j
jednako 15

Algoritmi i strukture podataka, 2006/07.

8.4.2007

45 / 46

Primjeri:
razred Trokut:
izgraditi razred Trokut koji e predstavljati koncept trokuta kao
geometrijskog lika koji ima definiranu duljinu svake od tri stranice i
g
funkcionalnost za izraunavanje
j ppovrine i opsega
p g trokuta
ugraenu
P08_Trokut

razred KompleksniBroj:
izgraditi razred KompleksniBroj koji e predstavljati (matematiki)
koncept kompleksnog broja. Razred mora sadravati dvije varijable koje e
predstavljati realni i imaginarni dio i pruati funkcionalnost za obavljanje
matematikih operacija s kompleksnim brojevima (zbrajanje, oduzimanje,
mnoenje i dijeljenje)
P09_KompleksniBroj
p
j
Algoritmi i strukture podataka, 2006/07.

8.4.2007

46 / 46