Objektno programiranje
Glava 6
Klase i objekti
Dosad smo u knjizi prouˇcavali primere programa koji nisu bili objektno orijenti-
sani, ve´c su koristili tehnike proceduralnog programiranja. Da bi se pisali objektno
orijentisani programi, moraju se koristiti klase, i njihovi primerci, odnosno objekti.
Klase i objekti su toliko važni za C++ da im je ostatak knjige u potpunosti posve´cen.
6.1. Kako i zašto je nastalo objektno orijentisano programiranje?
Tehnike proceduralnog programiranja usredsre ¯
dene su na procedure, odnosno
operacije koje se obavljaju u programu. Podaci se obiˇcno ˇcuvaju u promenljivama,
a sa njima rade funkcije. Podaci i funkcije koje rade sa njima potpuno su odvojeni.
Program radi tako što se promenljive prosle ¯
duju funkcijama, koje rade nešto sa njima
i vra´caju rezultat. Dakle, proceduralno programiranje je prvenstveno orijentisano na
funkcije. Me ¯
dutim, ovakav pristup prouzrokuje dva velika problema:
— Preterano koriš´cenje globalnih podataka: programeri ˇcesto pribegavaju ˇcuvanju
najvažnijih podataka u globalnim promenljivama, da bi im se lako pristupalo iz
svih funkcija u programu. Me ¯
dutim, tako se istovremeno otvaraju vrata za neho-
tiˇcno uništavanje ili ošte´civanje najvažnijih podataka.
— Projektovanje složenih programa koji se teško održavaju i menjaju: Iako je pre-
poruˇcljivo da se program uˇcini veoma modularnim, tj. da se izdeli u veliki broj
logiˇckih funkcija, postoji granica koju je programer u stanju da sagleda. Realni
programi imaju na stotine funkcija ˇciju interakciju je veoma teško sagledati, pa
menjanje kôda postaje izuzetno teško. Pre bilo kakve izmene potrebno je razu-
meti kako ´ce promena uticati na druge delove programa.
Kako su programi postajali složeniji, programeri su shvatili da im je potreban meha-
nizam koji ´ce olakšati projektovanje i održavanje velikih aplikacija. Objektno orijen-
tisan pristup su smislili programeri kao naˇcin da sebi olakšaju život, tj. kao odgovor
na softversku krizu koja se ogledala u tome što se softver projektovao duže nego što
je predvi ¯
deno, koštao više nego što je predvi ¯
deno i nije zadovoljavao sve postavljene
zahteve.
Objektno orijentisan pristup, kako mu i ime kaže, usredsre ¯
den je na objekte koji
objedinjuju podatke i funkcije koje rade sa njima. Najvažniji princip koji se koristi pri-
120
Glava 6. Klase i objekti
likom definisanja objekata jeste
apstrakcija
. Objekti su apstrakcije pojmova iz stvar-
nog sveta, što znaˇci da se modeliraju tako da sadrže samo one osobine koje su bitne
za program. Na primer, ako klasa Osoba modelira pojam osobe iz stvarnog sveta, pro-
gramu je možda važno da zna koliko ta osoba ima godina i kako se zove, a nije bitno
kog je pola.
6.2. Pojam klase
Mehanizam klasa omogu´cuje korisnicima da definišu sopstvene tipove podataka.
Zbog toga se klase ˇcesto nazivaju i korisniˇcki definisani tipovi podataka. Klase se kori-
ste kao šablon kojim se modeliraju objekti sliˇcnih svojstava, a objekti su konkretni pri-
merci (instance) klase. Uoˇcavanje zajedniˇckih osobina (svojstava) objekata i njihovo
grupisanje u klasu naziva se apstrakcija. Klasa sadrži
podatke ˇclanove
(member data) i
funkcije ˇclanice
ili metode (member functions). Podaci ˇclanovi najˇceš´ce predstavljaju
unutrašnjost klase, tj. njenu realizaciju, a funkcije ˇclanice njen interfejs, odnosno ono
što se može raditi sa njenim objektima.
Klasa se deklariše pomo´cu kljuˇcne reˇci
class
. Opšti oblik deklaracije klase je
class ime { lista £lanova } lista objekata;
Ime klase postaje novi tip koji se može koristiti za kreiranje objekata klase (odno-
sno promenljivih koje su tipa te klase). Iza deklaracije klase mogu se navesti nazivi
objekata, ali to nije obavezno. Klasa može da sadrži privatne i javne ˇclanove; stan-
dardno su svi ˇclanovi klase privatni. To znaˇci da im mogu pristupati iskljuˇcivo drugi
ˇclanovi iste klase. Na taj naˇcin postiže se OO princip kapsuliranja ili skrivanja poda-
taka. Da bi se delovi klase uˇcinili javnim, tj. da bi se omogu´cio pristup iz drugih delova
programa, oni se moraju deklarisati kao javni pomo´cu kljuˇcne reˇci
public
. Klase se
po pravilu projektuju tako da su podaci ˇclanovi privatni, a funkcije ˇclanice javne.
Iako nema sintaksnog pravila koje to nalaže, dobro projektovana klasa trebalo bi
da definiše samo jednu logiˇcku celinu. Na primer, u klasi koja ˇcuva imena i telefonske
brojeve ne bi trebalo da se na ¯
du i informacije o berzi, broju sunˇcanih sati u godini niti
bilo šta drugo. Dobro projektovane klase grupišu logiˇcki povezane informacije.
Da ponovimo: u jeziku C++, klasa kreira nov tip podataka koji se može koristiti
za kreiranje objekata. Klasa je logiˇcki okvir koji definiše vezu izme ¯
du svojih ˇclanova.
Kada se deklariše promenljiva tipa klase, zapravo se kreira objekat te klase i za njega
se odvaja prostor u memoriji.
Kao primer prouˇci´cemo klasu koja ˇcuva informacije o vozilima, kao što su au-
tomobili, kombiji i kamioni. Tu klasu nazva´cemo
Vozilo
i u nju ´cemo smestiti tri
podatka o vozilu: broj mesta za putnike, kapacitet rezervoara za gorivo i proseˇcnu
potrošnju goriva.

122
Glava 6. Klase i objekti
! "#
$
! $#
$
!
% &##
!
% &##
'' )* ) '' ''
)
)
'' '' ) ) ''
'' )* ) '' ''
)
)
'' '' ) ) ''
#
+
Rezultat izvršavanja:
U kombi staje 7 putnika i sa punim rezervoarom prelazi 800 kilometara.
U auto staje 5 putnika i sa punim rezervoarom prelazi 1000 kilometara.
Funkcija
main()
kreira dva objekta klase
Vozilo
koji se zovu
kombi
i
automobil
.
Zatim pristupa podacima ˇclanovima tih objekata dodeljuju´ci im vrednosti. Kôd u
funkciji
main()
može da pristupi ˇclanovima klase
Vozilo
zato što su deklarisani kao
javni (
public
). U prethodnom primeru važno je uoˇciti da svaki objekat ima sop-
stvene kopije svojih podataka ˇclanova definisanih u klasi. Izme ¯
du objekata
kombi
i
automobil
nema nikakve veze osim ˇcinjenice da su istog tipa: svaki od njih ima sop-
stvene vrednosti za podatke ˇclanove
brojMesta
,
kapacitetRezervoara
i
potrosnja
.
Ve´cina klasa osim podataka ˇclanova ima i
funkcije ˇclanice
. U opštem sluˇcaju,
funkcije ˇclanice rade sa podacima ˇclanovima i komuniciraju sa drugim delovima pro-
grama. Funkcija
main()
u prethodnom primeru raˇcunala je autonomiju vozila tako
što je kapacitet rezervoara delila potrošnjom. To je zadatak koji tipiˇcno treba da oba-
vlja funkcija ˇclanica klase, koju ´cemo sada dodati u klasu
Vozilo
zadavanjem njenog
prototipa u deklaraciji:
6.2. Pojam klase
123
class Vozilo {
public:
int brojMesta;
int kapacitetRezervoara;
int potrosnja;
int autonomija(); //funkcija clanica klase
};
Pošto se u deklaraciji klase navodi samo prototip funkcije ˇclanice, a ne i njena im-
plementacija, na mestu gde se piše implementacija funkcije ˇclanice mora se navesti
kojoj klasi ona pripada. Za tu svrhu se koristi operator razrešenja dosega (::):
//implementacija funkcije clanice autonomija
int Vozilo::autonomija() {
return kapacitetRezervoara / potrosnja * 100;
}
Operator razrešenja dosega :: povezuje ime klase sa nazivom njene funkcije ˇclanice
da bi kompajler znao na koju klasu se odnosi funkcija ˇclanica. Pošto više razliˇcitih
klasa mogu da imaju funkcije ˇclanice istog imena, operator :: je neophodan prili-
kom implementacije funkcije ˇclanice. U ovom sluˇcaju, operator razrešenja dosega
povezuje funkciju
autonomija()
sa klasom
Vozilo
, odnosno deklariše da je funk-
cija
autonomija()
u dosegu klase
Vozilo
. Telo funkcije autonomija ima samo jednu
naredbu; pošto svaki objekat tipa
Vozilo
ima sopstvenu vrednost podataka ˇclanova
kapacitetRezervoara
i
potrosnja
, izraˇcunava´ce se autonomija za svaki objekat
posebno.
Primetite da je sintaksa definicije funkcije ˇclanice takva da se prvo navodi njen
povratni tip.
Unutar funkcije
autonomija()
podacima ˇclanovima
kapacitetRezervoara
i
potrosnja
pristupa se direktno, bez navo ¯
denja imena objekta ili taˇcke. Kada funk-
cija ˇclanica koristi podatak ˇclan svoje klase, ona to radi bez eksplicitnog pozivanja
objekta. To je zato što se funkcija ˇclanica nikad ne poziva samostalno, ve´c se uvek
poziva za neki objekat svoje klase, pa nema potrebe da se objekat ponovo navodi.
Postoje dva naˇcina pozivanja funkcije ˇclanice. Ako se ona poziva iz kôda koji se
nalazi izvan klase, mora se pozivati preko nekog objekta i operatora taˇcka:
kombi.autonomija();
Kada se pozove na ovaj naˇcin, funkcija
autonomija()
radi sa vrednostima poda-
taka ˇclanova objekta
kombi
. Drugi naˇcin pozivanja funkcije ˇclanice je iz druge funk-
cije ˇclanice iste klase. Kada jedna funkcija ˇclanice klase poziva drugu funkciju ˇclanicu
klase, to može da uradi direktno, bez operatora taˇcka, jer kompajler ve´c zna sa kojim
objektom radi.

6.4. Inline funkcije ˇclanice
125
6.4. Inline funkcije ˇclanice
Kada je telo funkcije ˇclanice ne samo deklarisano, ve´c i definisano unutar dekla-
racije klase, kaže se da je funkcija ugra ¯
dena (inline).
class Brojac {
private:
int i;
public:
int broj { return ++i; } //inline funkcija clanica
};
Inline funkcije od prevodioca zahtevaju da kôd tela funkcije ugradi neposredno u kôd
programa na mestima poziva te funkcije, umesto uobiˇcajenog postupka poziva funk-
cije. Inline je zapravo zahtev za optimizaciju kôda koji kompajler može, ali ne mora da
ispuni. Funkcija ˇclanica se može se deklarisati kao
inline
i van deklaracije klase. To
se radi navo ¯
denjem specifikatora
inline
ispred deklaracije funkcije, kao u slede´cem
primeru:
inline int f() {
// ...
}
Mehanizam ugra ¯
divanja funkcija treba pažljivo primenjivati, samo za vrlo jednostavne
funkcije. Pri svakom pozivanju funkcije i povratku iz nje mora da se izvrši niz naredbi
(npr. stavljanje argumenata na stek i skidanje vrednosti argumenata sa steka prili-
kom povratka). Ako se funkcija ugradi program se ubrzava, ali ako je suviše složena,
program postaje duži pa ugra ¯
divanje ne poboljšava efikasnost.
6.5. Konstruktori i destruktori
U prethodnim primerima podacima ˇclanovima objekata klase
Vozilo
ruˇcno smo
dodeljivali vrednosti pomo´cu niza naredbi:
kombi.brojMesta = 7;
kombi.potrosnja = 7;
Ovakav pristup ruˇcnog dodeljivanja vrednosti oˇcigledno nije pogodan jer su mo-
gu´cnosti grešaka velike. C++ nudi bolji naˇcin za inicijalizaciju podataka ˇclanova, a to
je konstruktor.
Konstruktor
je funkcija ˇclanica klase koja se automatski poziva kada
se kreira objekat. Ima isto ime kao klasa, ali nema nikakav povratni tip (ˇcak ni
void
).
Sintaksa konstruktora izgleda ovako:
ime_klase( ) {
//telo konstruktora
}
Ovaj materijal je namenjen za učenje i pripremu, ne za predaju.
Slični dokumenti