You are on page 1of 27

KLASE I APSTRAKCIJA PODATAKA

Cilj poglavlja
Razumijevanje koncepta enkapsulacije i skrivanja podataka
Razumijevanje notacije apstrakcije podataka i apstraktnih tipova podataka (ADT)
Ovladavanje kreiranjem apstraktnih (korisnikih) tipova podataka (ADT) u C++ = KLASE
Ovladavanje vjetinom kreiranja, koritenja i unitavanja objekata
Ovladavanje pristupom atributima (podaci lanice) i metodama (funkcije lanice)

Programiranje u jeziku C

Proceduralno algoritamski orjentisano akcijski orjentisano


Jedinica programiranja funkcija
Programeri se koncentriu na pisanje funkcija, funkcije se grupiu u program
Podaci nisu primarni, oni su u funkciji podrke akcijama koje funkcije izvode
Glagoli su ti koji odreuju ta sistem radi i koji e to sistem funkcija biti implementiran
Instance ugraenih tipova (npr. int, char i sl.) nazivaju se promjenljive (varijable)

Programiranje u jeziku C++

Objektno orjentisano
Jedinica programiranja klasa (na osnovu koje se kreiraju objekti kao instance klase)
Programeri se koncentriu na kreiranje vlastitih tipova podataka KLASE
Imenice su te koje specificiraju sistem (imenice odreuju klase)
Svaka klasa sadri podatke i funkcije za manipulaciju podacima
Podaci koji se nalaze u klasi nazivaju se podaci lanice (data members)
Funkcije koje se nalaze u klasi nazivaju se funkcije lanice (metode)
Instance korisniki definisanih tipova (klasa) nazivaju se objekti

Klase su prirodna evolucija od struktura

Struktura se sastoji od vie razliitih meusobno logiki povezanih podataka

Primjer strukture:

struct Time {
int sat; // 0-23
int min; // 0-59
int sek; // 0-59
};

Mogue su sljedee instance ove strukture: promjenljiva (varijabla), niz, pokaziva, upuiva

Primjer:
Time timeObjekat, timeNiz[10], *timePtr, &timeRef = timeObjekat;

1
Implementacija (korisniki definisanih podataka) pomou strukture
Primjer kreiranja strukture, postavljanja lanica i ispisa
#include <iostream>
struct Time {
int sat; // 0-23
int min; // 0-59
int sek; // 0-59
};
void printMilitary( Time & );
void printStandard( Time & );
main()
{
Time vecera;
vecera.sat = 18; // postavljanje ispravnih vrijednosti
vecera.min = 30;
vecera.sek = 0;
cout << "Vrijeme za veceru u vojnom formatu: ";
printMilitary( vecera );
cout << " Vrijeme za veceru u standardnom formatu: ";
printStandard( vecera );
vecera.sat = 29; // postavljanje neispravnih vrijednosti
vecera.min = 73;
cout << "\nNekorektno vrijeme: " ;
printMilitary( vecera );
}
void printMilitary( Time &t )
{
cout << ( t.sat < 10 ? "0" : "" ) << t.sat << ":";
cout << ( t.min < 10 ? "0" : "" ) << t.min << endl;
}
void printStandard( Time &t )
{
cout << ( (t.sat == 12) ? 12 : t.sat % 12 ) << ":";
cout << ( t.min < 10 ? "0" : "" ) << t.min << ":" ;
cout << ( t.sek < 10 ? "0" : "" ) << t.sek ;
cout << ( t.sat < 12 ? " AM" : " PM" ) << endl;
}

Vrijeme za veceru u vojnom formatu: 18:30


Vrijeme za veceru u standardnom formatu: 6:30:00 PM

Nekorektno vrijeme: 29:73

Nekoliko je problema uoljivo ili se moe naslutiti ako se koriste strukture za kreiranje novih
tipova podataka:
Inicijalizacija podataka se ne zahtijeva prilikom kreiranja instance (promjenljive)
to moe da dovede do kasnijih problema u korienju podataka
ak i ako su inicijalizovani podaci, inicijalizacija moe biti nekorektna
pogrene vrijednosti mogu biti dodijeljene jer program direktno pristupa strukturi
ako se implementacija strukture promijeni (npr. ako se vrijeme pone izraavati u
sekundama proteklim od ponoi), itav program mora da se mijenja zato to PROGRAMER
DIREKTNO MANIPULIE PODACIMA I NJIHOVOM PREDSTAVOM
Nema interfejsa koji e omoguiti provjeru korektnosti i konzistentnost podataka

2
Implementacija (korisniki definisanih podataka) pomou klase
Klasa omoguava da se modeluje objekat koji ima:
atribute (podaci lanice data members)
ponaanje ili operacije (funkcije lanice member functions)

Funkcije lanice se u nekim drugim OO programskim jezicima zovu metode. Metode se izvravaju
kao odgovor na poruke (messages) koje se alju nekom objektu. Poruka je, u sutini, poziv funkcije
lanice od strane nekog objekta.

Najvanije karakteristike klase kao pravog tipa:


odreuju mogue vrijednosti objekata,
odreuju mogue operacije nad objektima,
spreavaju izvravanje bilo koje druge operacije nad objektima,
obezbjeuju obaveznu inicijalizaciju objekata pri njihovom stvaranju,
obezbjeuju unitavanje objekata kada vie nisu potrebni.

Definicija klase

Klasa se definie korienjem kljune rijei class.

Opti oblik definicije klase:

class ime {
tip clan; privatne lanice klase sve do
... prve oznake public
public:
tip clan; javne lanice klase
...
private:
tip clan; privatne lanice klase
...
};

Primjer definicije klase:

class Time {
public:
Time();
void setTime( int , int , int );
void printMilitary();
void printStandard();
private:
int sat; // 0 23
int min; // 0 59
int sek; // 0 59

};

3
Specifikatori pristupa lanicama:
public: sve lanice koje su definisane iza public su javne
dostupne su iz bilo kojeg dijela programa u kojem je dostupan objekat date klase
moe da im se pristupa i iz unutranjosti klase
uobiajeno je da su funkcije lanice javne lanice

private: sve lanice koje su definisane iza private su privatne


dostupne su samo funkcijama lanicama date klase
(moe da im se pristupa samo iz unutranjosti klase)
takoe mogu da im pristupaju i tzv. prijateljske funkcije (bie rijei kasnije)
uobiajeno je da su atributi (podaci lanice) privatne lanice klase (ali ne moraju biti)
ako imamo i neku privatnu metodu, nju mogu da pozivaju samo druge metode iz te klase

postoji i protected (o tome kasnije kod nasljeivanja)

specifikatori mogu da mijenjaju mjesta, mogu vie puta da se navode

U prethodnom primjeru imamo etiri javne funkcije lanice (Time, setTime, printMilitary,
printStandard). To su javne funkcije lanice ili javne usluge ili javne operacije (ponaanja) koje e
koristiti klijenti klase. Dakle, javne funkcije lanice pruaju neku uslugu klijentima klase, tanije funkcije
lanice neke metode omoguavaju interakciju sa objektima klase.

U prethodnom primjeru postoji funkcija lanica sa istim imenom kao i sama klasa. Ta funkcija
lanica naziva se konstruktor.
Konstruktor je specijalna funkcija lanica koja automatski poziva prilikom kreiranja objekta i
slui da bi se inicijalizovali podaci lanice prilikom kreiranja tog objekta.
Mogue je da klasa ima vie konstruktora (preklapanje imena funkcija).
Konstruktor ne vraa nikakav tip (ak ni void!)

Klasa je tip podataka. Kad je klasa definisana mogu se definisati i njene instance (objekat, niz
objekata, pokaziva na objekat i upuiva)

Primjer:

Time vrijeme; // objekat tipa Time


Time nizTime[10]; // niz objekata tipa Time
Time *pT; // pointer na objekat tipa Time
Time &uT = vrijeme; // upucivac na objekat tipa Time

Deklaracija klase

Definicija klase podrazumijeva da se navedu sve lanice klase.

Deklaracija podrazumijeva da se samo deklarie (naznai) da neki identifikator


predstavlja klasu

Opti oblik deklaracije klase:

class ime;

Poslije deklaracije klase, mogu samo da se definiu pokazivai na objekte te klase.


Ne mogu da se definiu objekti jer se ne zna kakva je klasa i koliko memorije treba.

4
Primjer:
#include <iostream.h>
// definicija klase Time
class Time { public:
Time(); // konstruktor
void setTime( int , int , int );
void printMilitary();
void printStandard();
private:
int sat; // 0 - 23
int min; // 0 - 59
int sek; // 0 - 59
};
// definicija konstruktora
Time::Time()
{ sat = min = sek = 0; }
// definicija ostalih funkcija clanica
void Time::setTime( int h, int m, int s )
{
sat = ( h >= 0 && h < 24 ) ? h : 0;
min = ( m >= 0 && m < 60 ) ? m : 0;
sek = ( s >= 0 && s < 60 ) ? s : 0;
}
void Time::printMilitary()
{
cout << ( sat < 10 ? "0" : "" ) << sat << ":" ;
cout << ( min < 10 ? "0" : "" ) << min;
}
void Time::printStandard()
{
cout << ( (sat == 12) ? 12 : sat % 12 ) << ":" ;
cout << ( min < 10 ? "0" : "" ) << min << ":" ;
cout << ( sek < 10 ? "0" : "" ) << sek ;
cout << ( sat < 12 ? " AM" : " PM" );
}

// glavni program
main()
{
Time t; // kreira objekat t klase Time
cout << "Inicijalno vrijeme : ";
t.printMilitary();
cout << " ili ";
t.printStandard();
t.setTime( 13, 27, 6 );
cout << "\n\nNovo vrijeme : "; t.printMilitary();
cout << " ili "; t.printStandard();
t.setTime( 99, 99, 99 ); // uzaludan pokusaj
cout << "\n\nNovi pokusaj : "; t.printMilitary();
cout << " ili "; t.printStandard();
}

Inicijalno vrijeme : 00:00 ili 0:00:00 AM


Novo vrijeme : 13:27 ili 1:27:06 PM
Novi pokusaj : 00:00 ili 0:00:00 AM

5
U prethodnom primjeru, glavni program kreira objekat t klase Time. Kad se objekat instancira
(kreira), automatski se poziva konstruktor Time() i inicijalizuje privatne atribute na nulu. Nakon toga
se to poetno vrijeme ispisuje u oba formata.
Potom se postavlja novo vrijeme pozivom funkcije lanice setTime, i vri odgovarajui ispis.
Nakon toga se pokuava definisati novo vrijeme, ali setTime to ne dozvoljava.

U prethodnom primjeru atributi ne mogu biti inicijalno postavljeni na neku eljenu


vrijednost, jer ih konstruktor postavlja na nulu. Postavljanje nenultih poetnih vrijednosti (u
ovom primjeru) mogue je samo pozivom funkcije lanice setTime.

Funkcije lanice mogu da se definiu i unutar definicije klase. Meutim, praksa pokazuje
da je bolje da definicija klase sadri samo deklaraciju funkcija lanica (prototip), a da se
funkcije lanice onda definiu izvan definicije klase.

Primjer:

class Count {
public:
void print()
{ cout << x << endl; }

private:
int x;
};

Ako su funkcije lanice definisane izvan definicije klase, prilikom njihove definicije
koristi se operator za razrjeenje dosega kako bi se naglasilo da su to funkcije lanice date
klase. (Ovo je pogotovo bitno ako vie klasa ima funkcije lanice koje se isto zovu)

Funkcije lanice implicitno znaju da treba da koriste atribute (podatke lanice) klase, pa nema
potrebe za argumentima, to pozive metoda ini konciznijim nego pozive funkcija kod proceduralnog
programiranja.

6
Doseg (oblast definisanosti) klase i pristup lanicama klase
lanice klase dostupne su svim ostalim lanicama date klase i referenciraju se koritenjem svog imena.

Izvan klase, lanice klase mogu da se referenciraju pomou


imena objekta,
pokazivaa na objekat, ili
upuivaa na objekat.

Funkcije lanice mogu da se preklapaju. Tada treba u definiciji klase navesti prototip za sve
preklopljene fukcije, a izvan definicije klase dati definiciju svake od tih preklopljenih funkcija.

Promjenljive definisane u nekoj funkciji lanici vidljive su samo u toj funkciji.


Ako je unutar metode definisana promjenljiva sa istim imenom kao atribut (podatak lanica)
klase, onda data promjenljiva maskira atribut u toj metodi. Maskiranom atributu moe da se
pristupi pomou operatora za razrjeenje dosega (::).

Primjer:

#include <iostream.h>

int x; // globalna promjenljiva

class Klasa {
public:
Klasa(); // konstruktor
void primjer();
private:
int x; // atribut
};

Klasa::Klasa() { x = 100; }

void Klasa::primjer()
{
int x=1; // lokalna promjenljiva

cout << "Lokalno x : " << x << endl;


cout << "Atribut x : " << Klasa::x << endl;
cout << "Globalno x : " << ::x << endl;
}

main()
{
Klasa t;
t.primjer();
}

Lokalno x : 1
Atribut x : 100
Globalno x : 0

7
lanicama klase pristupa se korienjem istih operatora kao da se radi o strukturi.

objekat.clanica
pointerNaObjekat->clanica ili (*pointerNaObjekat).clanica

Primjer:

#include <iostream.h>

class Count {
public:
int x;
void print() { cout << x << endl; }
};

main()
{
Count counter; // kreira objekat counter
Count *counterPok = &counter; // pointer na counter
Count &counterRef = counter; // upucivac na counter

counter.x = 7; // postavi vrijednost pomocu objekta


counter.print(); // poziv metode pomocu objekta

counterRef.x = 8; // postavi vrijednost pomocu upucivaca


counterRef.print(); // poziv metode pomocu upucivaca

counterPok->x = 10; // postavi vrijednost pomocu pointera


counterPok->print(); // poziv metode pomocu pointera
}

7
8
10

Ovdje je koriten public atribut! Ovo treba izbjegavati!


Koriten je samo radi ilustracije pristupa!

8
Organizacija veih programa
Kod realizacije veih programa, preporuljivo je razdvojiti kod u vie fajlova, tj. odvojiti interfejs od
implementacije.

Primjer:

Deklaracija klase (interfejs) u fajlu PRIMJER.H


#ifndef PRIMJER_H
#define PRIMJER_H
class Time { public:
Time();
void setTime( int , int , int );
void printMilitary();
void printStandard();
private:
int sat;
int min;
int sek;
};
#endif

Implementacija klase u fajlu PRIMJER.CPP


#include <iostream.h>
#include <primjer.h>
Time::Time()
{ sat = min = sek = 0; }
void Time::setTime( int h, int m, int s )
{
sat = ( h >= 0 && h < 24 ) ? h : 0;
min = ( m >= 0 && m < 60 ) ? m : 0;
sek = ( s >= 0 && s < 60 ) ? s : 0;
}
void Time::printMilitary()
{
cout << ( sat < 10 ? "0" : "" ) << sat << ":" ;
cout << ( min < 10 ? "0" : "" ) << min;
}
void Time::printStandard()
{
cout << ( (sat == 12) ? 12 : sat % 12 ) << ":" ;
cout << ( min < 10 ? "0" : "" ) << min << ":" ;
cout << ( sek < 10 ? "0" : "" ) << sek ;
cout << ( sat < 12 ? " AM" : " PM" );
}

Glavni program u fajlu PROJEKAT.CPP


#include <iostream.h>
#include <primjer.h>
main()
{
Time t;
cout << "Inicijalno vrijeme : ";
t.printMilitary();
cout << " ili ";
t.printStandard();
}

9
Pomone funkcije u klasi
Ne moraju sve funkcije lanice da budu javne, pogotovo ako one nisu dio interfejsa klase.
Ako neka funkcija slui kao pomona funkcija (helper function ili utility function)u klasi tako to je
njena uloga da npr. neto rauna ili slino za neku drugu funkciju lanicu klase, tada takvu pomonu
funkciju ostavljamo kao privatnu.
Funkcije lanice koje ine interfejs klase, odnosno omoguavaju pristup privatnim lanovima klase
nazivamo i pristupne funkcije (access functions).
Funkcije lanice koje provjeravaju ispunjenost ili neispunjenost nekog uslova (npr. da li je podatak
ovakav ili onakav, da li je tampa spreman, da li je lift zauzet i sl.) nazivaju se predikatske funkcije
(predicate functions).

Primjer:
#include <iostream.h>
class Prodaja { public: Prodaja();
void citajPodatke();
void postaviPodatak ( int , double );
void printTotal();
private: double total();
double iznos[7];
};
Prodaja::Prodaja()
{ for ( int i=0; i<7; iznos[i++] = 0.0 ); }
void Prodaja::citajPodatke()
{
double iznos;
cout << "Unesite dnevne iznose" << endl ;
for ( int i=1; i<=7; i++ )
{
cout << i << ". dan : ";
cin >> iznos;
postaviPodatak( i, iznos);
}
}
void Prodaja::postaviPodatak( int dan, double novac )
{
if ( dan >= 1 && dan <= 7 && novac >= 0 )
iznos[ dan-1 ] = novac;
else
cout << "Nekorektni podaci" << endl;
}
void Prodaja::printTotal()
{ cout << "Ukupna prodaja: " << total() << endl; }

// definicija (pomone funkcije)


double Prodaja::total() Unesite dnevne iznose
{ 1. dan : 1
double suma = 0.0; 2. dan : 10
for ( int i=0; i<7; i++) 3. dan : 20
suma+=iznos[i]; 4. dan : 100
return suma; 5. dan : 50
} 6. dan : 5
main() 7. dan : 0
{ Ukupna prodaja: 186
Prodaja p;
p.citajPodatke();
p.printTotal();
}

10
Inicijalizacija objekata - KONSTRUKTORI
Kad kreiramo neki objekat, njegovi atributi mogu se inicijalizovati konstruktorom date klase.

Konstruktor ima isto ime kao to je ime klase. Konstruktor se automatski poziva svaki put kad se kreira neki
objekat.

Konstruktori mogu da se preklapaju (tj. da imamo vie konstruktora sa preklopljenim imenima u istoj klasi),
tako se omoguava vie razliitih poetnih stanja za objekte koji se kreiraju.

Podaci lanice (atributi) ne moraju se inicijalizovati korienjem konstruktora, nego nekom drugom funkcijom
lanicom (kao u prethodnom primjeru). Takve klase, npr. nemaju konstruktor.
Praksa pokazuje da je bolje da se atributi inicijalizuju odmah prilikom kreiranja!

Iako programer eksplicitno ne poziva konstruktor pri kreiranju objekta, ipak je mogue u konstruktor
prenositi neke parametre kojima e se inicijalizovati atributi. Ovi parametri nazivaju se inicijalizatori i
navode se unutar zagrada prilikom deklaracije objekta. Ovi inicijalizatori predstavljaju argumente koji se
prosljeuju konstruktoru klase.

Podrazumijevani argumenti u konstruktoru

U narednom primjeru, konstruktor inicijalizuje atribute nulama.

class Time { public:


Time();
void setTime( int , int , int );
void printMilitary();
void printStandard();
private:
int sat, min, sek;
};
Time::Time()
{ sat = min = sek = 0; }

Konstruktor moe da sadri podrazumijevane argumente.

Podrazumijevane vrijednosti mogu da se Podrazumijevane vrijednosti mogu da se


navedu u prototipu konstruktora tada se ne navedu u definiciji konstruktora tada se ne
navode u definiciji konstruktora! navode u prototipu konstruktora!

Primjer: Primjer:

class Time { class Time {


public: public:
Time( int=0,int=0,int=0 ); Time( int, int, int );
void setTime( int,int,int ); void setTime( int,int,int );
void printMilitary(); void printMilitary();
void printStandard(); void printStandard();
private: private:
int sat, min, sek; int sat, min, sek;
}; };

Time::Time( int h, int m, int s ) Time::Time( int h=0,int m=0,int s=0 )


{ setTime( h, m, s ); } { setTime( h, m, s ); }

Nije dozvoljeno podrazumijevane vrijednosti navoditi i u prototipu i u definiciji!

11
Primjer:
#include <iostream.h>
class Time { public:
Time( int = 0, int = 0, int = 0);
void setTime( int , int , int );
void printMilitary();
void printStandard();
private:
int sat, min, sek;
};
Time::Time( int h, int m, int s )
{ setTime( h, m, s ); }
void Time::setTime( int h, int m, int s )
{
sat = ( h >= 0 && h < 24 ) ? h : 0;
min = ( m >= 0 && m < 60 ) ? m : 0;
sek = ( s >= 0 && s < 60 ) ? s : 0;
}
void Time::printMilitary()
{
cout << ( sat < 10 ? "0" : "" ) << sat << ":" ;
cout << ( min < 10 ? "0" : "" ) << min;
}
void Time::printStandard()
{
cout << ( (sat == 12) ? 12 : sat % 12 ) << ":" ;
cout << ( min < 10 ? "0" : "" ) << min << ":" ;
cout << ( sek < 10 ? "0" : "" ) << sek ;
cout << ( sat < 12 ? " AM" : " PM" );
}
main()
{
Time t1; // sve vrijednosti podrazumijevane
Time t2(2); // minute i sekunde podrazumijevane
Time t3(21,34); // sekunde podrazumijevane
Time t4(12,25,42); // nema podrazumijevanih vrijednosti
Time t5(27,74,99); // sve vrijednosti nekorektne
cout << "t1: "; t1.printMilitary();
cout << " ili "; t1.printStandard();
cout << endl;
cout << "t2: "; t2.printMilitary();
cout << " ili "; t2.printStandard();
cout << endl;
cout << "t3: "; t3.printMilitary();
cout << " ili "; t3.printStandard();
cout << endl;
cout << "t4: "; t4.printMilitary();
cout << " ili "; t4.printStandard();
cout << endl;
cout << "t5: "; t5.printMilitary(); t1: 00:00 ili 0:00:00 AM
cout << " ili "; t5.printStandard(); t2: 02:00 ili 2:00:00 AM
cout << endl; t3: 21:34 ili 9:34:00 PM
} t4: 12:25 ili 12:25:42 PM
t5: 00:00 ili 0:00:00 AM

12
DESTRUKTORI
Destruktor je, poput konstruktora, jo jedna specijalna funkcija lanica klase.

I destruktor ima isto ime kao i klasa (konstruktor), ali se ispred stavlja tilda (~).
Intuitivno se moe napraviti analogija sa bitskim operatorom negacije, jer se destruktor ponaa kao
komplement konstruktora.

Primjer:

class Time {
public:
Time();
void setTime( int , int , int );
void printMilitary();
void printStandard();
~Time();

private:
int sat, min, sek;
};

Destruktor se poziva kad se neki objekat unitava. Destruktor sutinski ne unitava objekat, on samo isti
memoriju.

Destruktor ne prima nikakve parametre niti vraa neku vrijednost.

Klasa moe imati samo jedan destruktor. Nije dozvoljeno preklapanje imena destruktora.

Destruktori su izuzetno korisni za klase iji objekti dinamiki alociraju memoriju. (o tome kasnije)

Kada se pozivaju KONSTRUKTORI I DESTRUKTORI?


Konstruktori i destruktori se pozivaju automatski.
Redoslijed kojim se pozivaju ove funkcije zavisi od redoslijeda kojim se ulazi i izlazi iz domena
u kojem se objekti kreiraju.
Generalno, destruktori se pozivaju obrnutim redoslijedom u odnosu na poziv konstruktora.
Postoje i situacije u kojima moe da se promijeni redoslijed pozivanja destruktora!
Za globalne objekte konstruktori se pozivaju prije bilo koje funkcije (i prije main funkcije) tj.
prije poetka izvravanja programa. (Redoslijed izvravanja konstruktora u sluaju vie fajlova nije
unaprijed poznat!)
Odgovarajui destruktori pozivaju se nakon zavretka izvravanja funkcije main.
Za lokalne objekte, konstruktori se pozivaju u trenutku kad se objekat definie. Odgovarajui
destruktor se poziva u trenutku naputanja bloka u kojem je objekat definisan.
Za automatske objekte, konstruktori i destruktori se pozivaju svaki put kad su ulazi i izlazi iz
domena.
Za statike objekte, konstruktori se pozivaju samo jedamput prilikom definisanja objekta.
Odgovarajui destruktor poziva se samo nakon zavretka izvravanja funkcije main.

13
Primjer:
#include <iostream.h>
class KonstDest {
public: KonstDest(int); // konstruktor
~KonstDest(); // destruktor
private: int data;
};
KonstDest::KonstDest( int x )
{
data = x;
cout << "Objekat " << data << " konstruktor";
}
KonstDest::~KonstDest()
{ cout << "Objekat " << data << " destruktor" << endl; }
void create( void )
{
KonstDest kd5(5);
cout << " (create: lokalni automatski)" << endl;
static KonstDest kd6(6);
cout << " (create: lokalni staticki)" << endl;
KonstDest kd7(7);
cout << " (create: lokalni automatski)" << endl;
}

KonstDest kd1(1); // globalni objekat


main()
{
cout << " (globalni kreiran prije main)" << endl;
KonstDest kd2(2);
cout << " (main: lokalni automatski)" << endl;
static KonstDest kd3(3);
cout << " (main: lokalni staticki)" << endl;
create();
KonstDest kd4(4);
cout << " (main: lokalni automatski)" << endl;
cout << "Izlaz iz programa" << endl;
}

Objekat 1 konstruktor (globalni kreiran prije main)


Objekat 2 konstruktor (main: lokalni automatski)
Objekat 3 konstruktor (main: lokalni staticki)
Objekat 5 konstruktor (create: lokalni automatski)
Objekat 6 konstruktor (create: lokalni staticki)
Objekat 7 konstruktor (create: lokalni automatski)
Objekat 7 destruktor
Objekat 5 destruktor
Objekat 4 konstruktor (main: lokalni automatski)
Izlaz iz programa
Objekat 4 destruktor
Objekat 2 destruktor
Objekat 6 destruktor
Objekat 3 destruktor
Objekat 1 destruktor

14
Objekat kd1 je globalni. Njegov konstruktor poziva se prije main funkcije. Njegov destruktor poziva se po
zavretku programa nakon to su svi ostali objekti uniteni.

Funkcija main kreira tri objekta. Objekti kd2 i kd4 su lokalni automatski. Konstruktor se za svakog od njih
poziva na mjestima gdje su ovi objekti definisani. Destruktori za ova dva objekta pozivaju se odmah nakon
to se napusti funkcija main.
Objekat kd3 je statiki. On postoji sve dok se program ne zavri. Njegov destruktor poziva se neposredno
prije unitavanja kd1.

Funkcija create kreira tri objekta automatske kd5 i kd7, te statiki kd6. Ovi objekti kreiraju se
redoslijedom kojim su i definisani u funkciji.
Poto su kd5 i kd7 automatski, njihovi destruktori pozivaju se automatski nakon izlaska iz funkcije.
Poto je kd6 statiki, on postoji sve dok se program izvrava. Njegov destruktor poziva se prije destruktora
za kd3 i kd1. Mora se unititi prije kd3 jer je poslije kd3 kreiran.
Da je kd6 kreiran prije kd3, tada bi se kd6 unitio poslije kd3.

Upotreba lanica klase


Privatnim atributima mogu da pristupe samo:
funkcije lanice date klase, i
"prijateljske" funkcije date klase (o tome kasnije)
Tipian primjer:
Neka imamo klasu BankovniRacun iji je privatni atribut stanjeRacuna.
Ovom atributu moe da se pristupa samo pomou funkcija lanica date klase.
Najee imamo metodu koja:
postavlja dati atribut tzv. set funkcija npr. setStanjeRacuna
ita dati atribut tzv. get funkcija npr. getStanjeRacuna
Get funkcije esto se nazivaju i query funkcije.
Naravno da bi se atributu moglo bez ogranienja pristupati izvan klase, ako bi se on proglasio javnim
(public). Meutim, tada "svako" moe da mijenja atribute. Moe da ih ispisuje kako eli, a to najee nije
cilj. ee je cilj obezbijediti atribute od neovlatenog i nekorektnog postavljanja vrijednosti, odnosno
ispisivati ih uvijek na neki standardizovan nain.
Softverska praksa upuuje na koritenje privatnih atributa uz implementaciju set/get metoda.

15
Primjer:
#include <iostream.h> void Time::printStandard()
class Time {
{ cout << ((sat==12) ? 12 : sat%12 );
public: cout << ":" ;
Time( int=0,int=0,int=0 ); cout << (min<10 ? "0":"" ) << min;
cout << ":" ;
void setTime( int,int,int ); cout << ( sek<10 ? "0":"" ) << sek;
void setSat( int ); cout << ( sat<12 ? " AM":" PM" );
void setMin( int ); }
void setSek( int );
void inkMin( Time &, const int );
int getSat();
int getMin(); main()
int getSek(); {
Time t;
void printMilitary();
void printStandard(); t.setSat(17);
t.setMin(34);
private: t.setSek(25);
int sat, min, sek; cout << "t1: " << t.getSat()
}; << ":" << t.getMin()
<< ":" << t.getSek() << endl;
Time::Time( int h, int m, int s )
{ setTime( h, m, s ); } t.setSat(234); t.setSek(6373);
cout << "t2: " << t.getSat()
void Time::setTime(int h,int m,int s) << ":" << t.getMin()
{ setSat(h); setMin(m); setSek(s); } << ":" << t.getSek() << endl;

void Time::setSat( int h ) t.setTime( 11,58,0 );


{ sat = ( h>=0 && h<24 ) ? h:0; } inkMin( t,3 );
}
void Time::setMin( int m )
{ min = ( m>=0 && m<60 ) ? m:0; } void inkMin ( Time &tt, const int x )
{
void Time::setSek( int s ) cout << "Pocetno vrijeme: ";
{ sek = ( s>=0 && s<60 ) ? s:0; } tt.printStandard();

int Time::getSat() { return sat; } cout << "\nInkrement za "


<< x << " minuta" << endl;
int Time::getMin() { return min; }
for ( int i=0; i<x; i++ )
int Time::getSek() { return sek; } {
tt.setMin( (tt.getMin()+1) % 60 );
void Time::printMilitary() if ( tt.getMin() == 0 )
{ tt.setSat( (tt.getSat()+1) % 24 );
cout << ( sat<10 ? "0":"" ) << sat; }
cout << ":" ;
cout << ( min<10 ? "0":"" ) << min; cout << "Novo vrijeme : ";
} tt.printStandard();
}

t1: 17:34:25
t2: 0:34:0
Pocetno vrijeme: 11:58:00 AM
Inkrement za 3 minuta
Novo vrijeme : 12:01:00 PM

16
Dodjeljivanje objekata "lan po lan"
Operator dodjele (=) moe se koristiti da bi se jedan objekat dodijelio drugom (istog tipa)

Ovakva dodjela je dodjela lan po lan (memberwise copy).


Svaka lanica (atribut) jednog objekta kopira se u odgovarajuu lanicu drugog objekta.

Ovaka pristup moe da proizvede neeljene probleme kod objekata sa dinamikom alokacijom.
(O tome e biti rijei kasnije)

Primjer:

#include <iostream.h>

class Date {
public:
Date( int = 1, int = 1, int = 2001 );
void print();
private:
int dd, mm, gg;
};

Date::Date( int d, int m, int g )


{ gg = g; mm = m; dd = d; }

void Date::print()
{ cout << dd << '.' << mm << '.' << gg; }

main()
{
Date dat1( 31, 12, 2004 );
Date dat2;

cout << "dat1 = "; dat1.print();


cout << "\ndat2 = "; dat2.print();

dat2 = dat1;
cout << "\n\nNakon kopiranja \ndat2 = ";
dat2.print();
}

dat1 = 31.12.2004
dat2 = 1.1.2001

Nakon kopiranja
dat2 = 31.12.2004

17
Konstantni objekti i konstantne funkcije lanice
Ranije smo vidjeli kako se definiu konstante instance standadnih tipova, koritenjem const.
Kljuna rije const moe da se koristi da se specificira da li neki objekat konstantan. Svaki pokuaj promjene
takvog objekta bie okarakterisan kao sintaksna greka.

Primjer:
Neka je definisana klasa:

class Time {
public:
Time(int = 0 , int = 0 , int = 0 );
void printMilitary();
void printStandard();
~Time();

private:
int sat, min, sek;
};

tada se sljedeim iskazom:

const Time podne( 12, 0, 0 );

definie konstantan objekat podne koji je postavljen na 12:0:0.

C++ kompajleri onemoguavaju poziv funkcija za konstantne objekte sve dok funkcija lanica
takoe nije deklarisana kao konstantna. Ovo vai ak i za get funkcije lanice!!!

Funkcija se proglaava konstantnom tako to se i u prototipu i u definiciji funkcije iza liste parametara, a
prije tijela funkcije navede kljuna rije const.

Primjer:

Funkcija lanica koja treba da vrati sat za neki konstantan objekat se deklarie na sljedei nain:

int getSat() const;

odnosno, definicija:

int Time::getSat() const


{ return sat; }

Ako se za datu klasu nee definisati konstantni objekti za koje bi trebala da se poziva neka od
funkcija lanica, funkcije lanice ne moraju da se definiu kao konstantne.

Ako se za neku klasu i definie konstantan objekat, a za taj objekat se nee pozivati funkcije
lanice, tada funkcije lanice date klase ne moraju da se definiu kao konstantne.

Za konstruktore i destruktore ne moe se koristiti const!!! (Konstruktor mora moi postavljati


vrijednosti!)

Iz konstruktora je dozvoljeno i mogue pozivati funkciju lanicu koja nije konstatna za


konstantni objekat koji se kreira.

18
Primjer:

#include <iostream.h>
#include <math.h>

class Tacka
{
public:
Tacka ( double = 0 , double = 0 );
double getX() const;
double getY() const;
double daljina ( Tacka ) const;
void pisiTacka () const;
private:
double x, y;
};

Tacka::Tacka ( double xx, double yy)


{ x = xx; y = yy; }

double Tacka::getX () const


{ return x; }

double Tacka::getY () const


{ return y; }

double Tacka::daljina ( Tacka t ) const


{ return sqrt( pow(x-t.x,2) + pow(y-t.y,2) ); }

void Tacka::pisiTacka () const


{ cout << "(" << x << "," << y << ")"; }

main()
{
Tacka tA(3,4); // definisan objekat koji nije konstantan
const Tacka tO; // definisan konstantan objekat

// objekat tA nije konstantan i radi njega nema potrebe da getX() i getY()


// budu konstantne
cout << "Tacka A: " << tA.getX() << "," << tA.getY() << endl;

// medjutim, posto se getX() i getY() pozivaju i za tO koji je konstantan


// getX() i getY() moraju biti konstantne funkcije
cout << "Tacka O: " << tO.getX() << "," << tO.getY() << endl;

// sto se tice tA, funkcija pisiTacka() takoe ne mora biti konstantna


cout << "Tacka A: "; tA.pisiTacka(); cout << endl;

// ali radi tO, funkcija pisiTacka() mora biti konstantna


cout << "Tacka O: "; tO.pisiTacka(); cout << endl;

// sto se tice tA, ni funkcija daljina() ne mora biti konstantna


cout << "Udaljenost od A"; tA.pisiTacka();
cout << " do O"; tO.pisiTacka();
cout << " iznosi: " << tA.daljina(tO) << endl;

// ali radi tO, funkcija daljina() mora biti konstantna


cout << "Udaljenost od O"; tO.pisiTacka();
cout << " do A"; tA.pisiTacka();
cout << " iznosi: " << tO.daljina(tA) << endl;
}

Tacka A: 3,4
Tacka O: 0,0
Tacka A: (3,4)
Tacka O: (0,0)
Udaljenost od A(3,4) do O(0,0) iznosi: 5
Udaljenost od O(0,0) do A(3,4) iznosi: 5

19
Ako klasa sadri atribute koji nisu konstantni, tada se u konstruktoru inicijalizacija tih atributa
moe vriti na uobiajeni nain koritenjem operatora dodjele.
Npr.
Tacka::Tacka ( double xx, double yy) { x=xx; y=yy; }

Meutim, ako klasa sadri i neki konstantan atribut, tada se u konstruktoru inicijalizacija tih
konstantnih atributa ne moe vriti koritenjem operatora dodjele. Ako bi u prethodnoj klasi atribut
x bio konstantan, tada bi imali sljedei konstruktor:

Tacka::Tacka ( double xx, double yy) : x(xx) { y=yy; }

Ako bi u prethodnoj klasi oba atributa (x i y) bili konstantni, tada bi imali sljedei konstruktor:

Tacka::Tacka (double xx, double yy) : x(xx), y(yy) {}


Na ovaj nain moraju biti inicijalizovani konstantni atributi i upuivai.
(a i kasnije kod nasljeivanja e biti vie rijei o tome)

Primjer:

#include <iostream.h>

class Inkrement
{
public:
Inkrement( int b=0, int i=1 );
void dodaj() { brojac += korak; }
void print();
private:
int brojac;
const int korak; // konstantan atribut
};

Inkrement::Inkrement( int b, int i )


: korak ( i ) // inicijalizator za konstantan atribut
{ brojac = b; }

void Inkrement::print()
{
cout << "brojac=" << brojac << ", korak=" << korak << endl;
}

main()
{
Inkrement data( 10, 5 );

cout << "Prije petlje : ";


data.print();

for ( int j=1; j<4; j++ )


{
data.dodaj(); data.print();
}
}

Prije petlje : brojac=10, korak=5


brojac=15, korak=5
brojac=20, korak=5
brojac=25, korak=5

20
Kompozicija: OBJEKAT kao ATRIBUT
Kad jedan objekat kao atribut ima neki drugi objekat, govorimo o kompoziciji.
Neka klasa moe da sadri jedan ili vie objekata drugih klasa. Tako npr. automobil ima motor, tokove,
sjedita, volan...
Kad se neki objekat kreira, njegov konstruktor se automatski poziva, pa treba specificirati kako se argumenti
prenose konstruktoru objektu lanu. Objekti lanice se kreiraju redoslijedom kojim su deklarisani u
definiciji klase (a ne redom kojim su navedeni u listi inicijalizatora u konstruktoru) i to prije nego to se
kreira objekat koji sadri te objekte lanice (ovaj se objekat esto naziva host objekat)

Primjer:
#include <iostream.h> class Osoba {
class Datum { public:
public: Osoba( char *, int , int , int );
Datum( int=1, int=1, int=2000 ); void print() const ;
void print() const ; ~Osoba();
~Datum(); private:
private: char ime[15];
int dd, mm, gg; const Datum rodjen;
int provjeriDan( int ); };
};
Osoba::Osoba(char *s, int d, int m, int g)
Datum::Datum( int d, int m, int g ) : rodjen( d, m, g )
{ {
gg = g; int bs=0;
mm = (m>0 && m<=12) ? m : 1; while ((ime[bs]=*(s+bs)) && bs<14)
dd = provjeriDan ( d ); bs++;
cout << "Konstruktor za datum: "; if (bs==14) ime[bs]='\0';
print(); cout << endl; cout << "Konstruktor za osobu : "
} << ime << endl;
}
void Datum::print() const
{ cout << dd<<'.'<<mm<<'.'<<gg<<'.'; } void Osoba::print() const
{
Datum::~Datum()
cout << ime << " je rodjen: ";
{
rodjen.print();
cout << "Destruktor za datum: ";
cout << endl;
print(); cout << endl;
}
}
Osoba::~Osoba()
int Datum::provjeriDan( int dan )
{ cout << "Destruktor za osobu : "
{
<< ime << endl; }
static const int mjeseci[13] =
{0,31,28,31,30,31,30,31,31,30,31,30,31}; main()
if ( dan>0 && dan<=mjeseci[mm] ) {
return dan; Osoba otac ("Marko", 28,2,1975),
if ( mm==2 && dan==29 && sin ("Janko", 29,2,2000),
(gg%400==0 || (gg%4==0 && gg%100!=0))) pradeda("Slavko",29,2,1900);
return dan; otac.print(); sin.print();
return 1; pradeda.print();
} }

Konstruktor za datum: 28.2.1975.


Konstruktor za osobu : Marko
Konstruktor za datum: 29.2.2000.
Konstruktor za osobu : Janko
Konstruktor za datum: 1.2.1900.
Konstruktor za osobu : Slavko
Marko je rodjen: 28.2.1975.
Janko je rodjen: 29.2.2000.
Slavko je rodjen: 1.2.1900.
Destruktor za osobu : Slavko
Destruktor za datum: 1.2.1900.
Destruktor za osobu : Janko
Destruktor za datum: 29.2.2000.
Destruktor za osobu : Marko
Destruktor za datum: 28.2.1975.

21
Prijateljske funkcije i prijateljske klase
Prijateljska funkcija neke klase je funkcija definisana izvan dosega te klase, ali koja ima pravo
pristupa privatnim lanovima date klase. (kod nasljeivanja emo vidjeti da da moe i zatienim
lanicama te klase)
Da bi se funkcija deklarisala kao prijateljska funkcija klase, prototip te funkcije treba se navede u definiciji
date klase, pri emu prototip treba da zapoinje kljunom rijeju friend.
class Klasa {
friend tip funkcija... ;
...
}
Da bi se klasa A deklarisala kao prijateljska klasa klasi B, u definiciji klase B treba da se navede deklaracija:
class B {
friend class A ;
...
}
Sada su sve funkcije lanice klase A prijateljske funkcije klase B.
"Prijateljstvo se daruje, a ne uzima!!!".
Da bi klasa A bila prijatelj klasi B, klasa B mora eksplicitno da deklarie da joj je klasa A prijatelj.
"Prijateljstvo nije simetrino!!!".
Ako je klasa A prijatelj klase B to ne znai da je i klasa B prijatelj klasi A.
"Prijateljstvo nije tranzitivno!!!".
Ako je klasa A prijatelj klase B i ako je klasa B prijatelj klase C, to ne znai da je klasa A prijatelj klase C.
Mogue je koristiti i preklopljene prijateljske funkcije. Tada prototip svake od tih funkcija mora
biti deklarisan kao prijateljski u definiciji date klase.

Primjer:
#include <iostream.h>
class Data
{
friend void setX ( Data &, int ); // deklaracija prijatelja
public:
Data() { x=0; }
void print() const { cout << x << endl; }
private:
int x;
};
void setX( Data &dat, int val )
{
dat.x = val; // dozvoljeno: setX je prijatelj klase Data
}
main()
{
Data d;
cout << "d.x nakon kreiranja: "; d.print();
setX( d, 10 ); // postavi x pomocu prijatelja
cout << "d.x nakon poziva setX: ";
d.print(); d.x nakon kreiranja: 0
} d.x nakon poziva setX: 10

22
Pokaziva this
Osim formalnih argumenata, metode imaju i jedan "skriveni" argument (skriveni zato to se
ne vidi u prototipu funkcija). Taj argument je zapravo tekui objekat objekat za koji je
funkcija pozvana.

Adresa skrivenog argumenta (tekueg objekta) za vrijeme izvravanja funkcije lanice nalazi se
u pokazivau this. Svaki objekat ima pristup svojoj vlastitoj adresi preko pokazivaa this.

Pokaziva this se implicitno koristi za referenciranje lanica objekta (i atributa i funkcija).


Osim toga, pokaziva this moe i eksplicitno da se koristi.

Pokaziva this se ne koristi ba esto, ali najee se koristi:


- ako je tekui objekat vrijednost koju vraa metoda
- ako je tekui objekat argument neke funkcije
- za kaskadno pozivanje funkcija lanica

Primjer:
#include <iostream.h>
class Test {
public:
Test( int = 0 );
void print() const ;
private:
int x;
};

Test::Test( int a ) { x = a; }

void Test::print() const


{
cout << " x = " << x << endl;
cout << " this->x = " << this->x << endl;
cout << "(*this).x = " << (*this).x << endl;
}

main()
{
Test t(12); x = 12
t.print(); this->x = 12
} (*this).x = 12

U prethodnom primjeru ilustrovana je primjena this pokazivaa u funkciji lanici u kojoj se tampa vrijednost
privatnog atributa x datog objekta.
Navoenje *this.x bilo bi sintaksna greka jer je to *(this.x).

Jedna interesantna upotreba pokazivaa this je da se sprijei dodjela objekta samome sebi.
(vie rijei bie kod preklapanja operatora - kad "samododjela" moe dovesti do pozbiljnih greaka pri
dinamikoj alokaciji)

Druga interesantna upotreba pokazivaa this je omoguavanje kaskadnog pozivanja funkcija


lanica.

23
Primjer:

#include <iostream.h> int Time::getSat() const


class Time { return sat; }
{
public: int Time::getMin() const
Time( int=0, int=0, int=0 ); { return min; }
Time &setTime( int,int,int );
Time &setSat( int ); int Time::getSek() const
Time &setMin( int ); { return sek; }
Time &setSek( int );
int getSat() const ; void Time::printMilitary() const
int getMin() const ; {
int getSek() const ; cout << ( sat<10 ? "0":"" ) << sat;
void printMilitary() const ; cout << ":" ;
cout << ( min<10 ? "0":"" ) << min;
void printStandard() const ; }
private:
int sat, min, sek; void Time::printStandard() const
}; {
cout << ((sat==12) ? 12 : sat%12 );
Time::Time( int h, int m, int s ) cout << ":" ;
{ setTime( h, m, s ); } cout << (min<10 ? "0":"" ) << min;
Time &Time::setTime(int h,int m,int s) cout << ":" ;
{ cout << ( sek<10 ? "0":"" ) << sek;
cout << ( sat<12 ? " AM":" PM" );
setSat( h ); }
setMin( m );
setSek( s ); main()
return *this; // kaskada {
} Time t;
Time &Time::setSat( int h ) t.setSat(18).setMin(30).setSek(22);
{
sat = ( h>=0 && h<24 ) ? h : 0; cout << "Military : ";
return *this; t.printMilitary();
} cout << "\nStandard time: ";
t.printStandard();
Time &Time::setMin( int m )
{ cout << "\n\nNovo vrijeme: ";
min = ( m>=0 && m<60 ) ? m : 0; t.setTime(20,20,20).printStandard();
return *this; cout << endl;
} }
Time &Time::setSek( int s )
{
sek = ( s>=0 && s<60 ) ? s : 0;
return *this;
} Military : 18:30
Standard time: 6:30:22 PM

Novo vrijeme: 8:20:20 PM

U prethodnom primjeru funkcije lanice setTime, setSat, setMin i setSek vraaju *this jer su to metode
iji je tip Time &. Ovakve funkcije lanice omoguavaju kaskadno pozivanje.
Asocijativnost operatora "." je slijeva udesno, pa iskaz
t.setSat(18).setMin(30).setSek(22);
zapravo znai sljedee: Prvo se izvrava t.setSat(18) to vraa upuiva na objekat t. Preostaje
t.setMin(30).setSek(22). Izvrava se t.setMin(30) to vraa upuiva na objekat t, pa preostaje
t.setSek(22).

Slino imamo i za iskaz


t.setTime(20,20,20).printStandard();

24
Statiki (zajedniki) lanovi klase
Prilikom definisanja klase, lanice mogu da se proglase statikim stavljanjem kvalifikatora
static ispred date lanice. Ovakvom definicijom se lanica proglaava zajednikom za sve
objekte date klase stvorene tokom izvravanja programa.
lanice klase koje nisu zajednike, nazivaju se pojedinane lanice.
I atributi i funkcije lanice mogu biti zajedniki

Zajedniki atributi
Ako je atribut zajedniki, to znai da postoji samo jedan primjerak tog atributa, bez obzira na broj objekata.
Pristup zajednikom atributu je pristup istoj memorijskoj lokaciji.
Mijenjanjem vrijednosti zajednikog atributa utie se na stanje svih objekata te klase.
Primjer:
class Klasa {
...
static int a; // definicija zajednickog clana
int b; // definicija pojedinacnog clana
...
}
int Klasa::a = 55; // zajednicki atribut za sve objekte Klase

Zajednike funkcije lanice


Zajednike funkcije lanice ne posjeduju pokaziva this
Mogu da pristupaju samo zajednikim lanovima (ako se navede samo identifikator lana)
Mogu da pristupaju pojedinanim lanovima (samo za konkretne objekte)
Primjer:
class Klasa {
static int a; // zajednicki clan
int b;
public: static int f(); // zajednicka metoda
static void g (Klasa, Klasa *, Klasa &); // zajednicka
int h(int);
};
int Klasa::a=55; // definicija zajednickog clana
int Klasa::f()
{
int i=a; // metoda f moze da pristupa zajednickom atributu
int j=b; // metoda f ne moze da koristi zajednicki atribut
return i+j;
}
void Klasa::g(Klasa x, Klasa *y, Klasa &z)
{
int i = x.b; // metoda g je zajednicka metoda
int j = y->b; // pa moze da pristupa pojedinacnim atributima
z.b = i + j; // konkretnih objekata
}
int Klasa::h( int x ) // metoda h je pojedinacna i moze da pristupa svim
{ return (a+b)*x; } // atributima, i pojedinacnim i zajednickim
main()
{
int p=Klasa::f(); // f moze da se pozove bez konkretnog objekta
int q=Klasa::h(5); // h ne moze da se pozove bez konkretnog objekta
Klasa k;
Klasa::g(k,&k,k);
int s=k.h(6);
}

25
Zadatak

Kreirati klasu Complex za aritmetike operacije nad kompleksnim brojevima.


Realni i imaginarni dio kompleksnog broja posmatrati kao privatne atribute tipa double.
Treba omoguiti inicijalizaciju prilikom kreiranja objekta eljenim vrijednostima. Ako se vrijednosti ne navedu
uzeti da se radi o broju 0.
Napisati javne funkcije lanice za:
sabiranje dva kompleksna broja,
tampanje kompleksnog broja u obliku (re,im).

Rjeenje:

#include <iostream.h>

class Complex {
public:
Complex ( double = 0, double = 0 );
Complex saberiComplex (Complex &);
void printComplex ();
private:
double re, im;
};

Complex::Complex( double real, double imag )


{ re = real; im = imag; }

Complex Complex::saberiComplex ( Complex &c )


{
Complex pom;
pom.re = re + c.re;
pom.im = im + c.im;
return pom;
}

void Complex::printComplex()
{ cout << "(" << re << "," << im << ")"; }

main()
{
Complex c1(1,3), c2(2,5), c3;

cout << "Prvi broj: ";


c1.printComplex();
cout << endl;

cout << "Drugi broj: ";


c2.printComplex(); Prvi broj: (1,3)
cout << endl; Drugi broj: (2,5)
Zbir: (3,8)
cout << "Zbir: ";
c3=c1.saberiComplex(c2);
c3.printComplex();
cout << endl;
}

Za vjebu:

Dodati i ostale funkcije lanice u datu klasu (oduzimanje, mnoenje, modul...)

26
Zadatak

Kreirati klasu Razlomak za aritmetike operacije nad razlomcima.


Brojilac i imenilac posmatrati kao privatne atribute tipa int.
Treba omoguiti inicijalizaciju prilikom kreiranja objekta eljenim vrijednostima. Ako se vrijednosti ne navedu
uzeti da se radi o broju 0.
Napisati javne funkcije lanice za:
sabiranje dva razlomka,
tampanje razlomka u obliku broj/imen.

Rjeenje:

#include <iostream.h>
class Razlomak
{
public:
Razlomak ( int = 0, int = 1 );
Razlomak saberi ( Razlomak & );
void printRazlomak ( void );
private:
int broj;
int imen;
};

Razlomak::Razlomak( int b, int n )


{
broj = b; imen = n;
}

Razlomak Razlomak::saberi( Razlomak &r )


{
Razlomak t;
t.broj = r.broj * imen + r.imen * broj;
t.imen = r.imen * imen;
return t;
}

void Razlomak::printRazlomak ( void )


{
if ( imen == 0 )
cout << "\nGRESKA!!!" << '\n';
else if ( broj == 0 )
cout << 0;
else
cout << broj << '/' << imen;
}
1/3 + 7/8 = 29/24
int main()
{
Razlomak c( 1, 3 ), d( 7, 8 ), x;
c.printRazlomak();
cout << " + ";
d.printRazlomak();
x = c.saberi( d );
cout << " = ";
x.printRazlomak();
cout << '\n';
}

Za vjebu:

Dodati i ostale funkcije lanice u datu klasu (oduzimanje, mnoenje, dijeljenje, skraivanje...)

27

You might also like