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.

background image

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.

background image

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

}

Želiš da pročitaš svih 26 strana?

Prijavi se i preuzmi ceo dokument.

Ovaj materijal je namenjen za učenje i pripremu, ne za predaju.

Slični dokumenti