You are on page 1of 28

Objektno orijentisano programiranje 1

Preklapanje operatora

Pojam preklapanja operatora




Ako su u programu potrebni kompleksni brojevi i operacije nad njima


pogodno je da se operacije mogu predstaviti standardnim operatorima na primer: Complex c1(1,2),c2(3,4),c3; c3=c1+c2; defini u se nova zna enja operatora za korisni ke tipove (klase) princip je sli an kao kod preklapanja imena funkcija

C++ dozvoljava preklapanje operatora (operator overloading)


   

Preklopljeni operatori za klasne tipove su specijalne operatorske funkcije Operatorske funkcije nose ime operator@

simbol @ predstavlja neki operator ugra en u jezik

Operatorske funkcije preklapaju standaradne operatore (+, -, *, /, ...) Pozivanje operatorskih funkcija u izrazima

mo e biti notaciono isto kao i kori izraz t1@t2 se tuma i kao:


 

enje operatora nad ugra enim tipovima

operator@(t1,t2) // za operatorsku prijateljsku funkciju klase t1.operator@(t2) // za operatorsku metodu klase

Preklapanje operatora

30.10.2005.

Primer operatorskih funkcija


class Complex { public: Complex(double,double); /* konstruktor */ friend Complex operator+(Complex,Complex); /* oparator + */ friend Complex operator-(Complex,Complex); /* operator - */ private: double real, imag; }; Complex::Complex (double r, double i) : real(r), imag(i) {} Complex operator+ (Complex c1, Complex c2) { Complex c(0,0); c.real=c1.real+c2.real; c.imag=c1.imag+c2.imag; return c; } Complex operator- (Complex c1, Complex c2) { return Complex(c1.real-c2.real,c1.imag-c2.imag); } Complex c1(1.0,1.0),c2(2.0,2.0),c3(0,0); c3=c1+c2; /* poziva se operator+(c1,c2) */ c1=c2-c3; /* poziva se operator-(c2,c3) */

Preklapanje operatora

30.10.2005.

Organi enja preklapanja operatora




Postoje neka ograni enja u preklapanju operatora:


ne mogu da se preklope operatori: ., .*, ::, ?:, sizeof i throw dok svi ostali mogu ne mogu da se redefini u zna enja operatora za primitivne (standardne) tipove podataka ne mogu da se uvode novi simboli za operatore ne mogu da se menjaju osobine operatora: n-arnost, prioritet i asocijativnost neki operatori imaju posebna ograni enja za preklapanje: new, delete, i++, i--, =, (), [], ->, (tip)

Preklapanje operatora

30.10.2005.

Pravila o preklapanju operatora




Operatorske funkcije mogu biti:

metode
 

kod kojih je skrivreni argument levi (za binarne) ili jedini (za unarne) operand po prirodi stvari, levi operand mora biti tipa klase ija je metoda lanica kod kojih je bar jedan argument tipa date klase

globalne prijateljske funkcije




Za korisni ke tipove su unapred definisani slede i operatori:


= (dodela vrednosti), & (uzimanje adrese), .(pristup lanu), , (lan anje) sve dok ih korisnik ne redefini e (osim .), oni imaju podrazumevano zna enje * (indirektno adresiranje), -> (posredan pristup lanu), [] (indeksiranje) sve dok ih korisnik ne redefini e, i oni imaju podrazumevano zna enje

Za izvedene (pokaziva ke) tipove iz korisni kih tipova definisani su:


  

Vrednosti operatorskih funkcija mogu da budu bilo kog tipa, pa i void Ako se simbol operatora sastoji od slova (npr. new), mora se pisati odvojeno od klju ne re i operator Operatorske f-je ne mogu da imaju podrazumevane vrednosti argumenata
Preklapanje operatora 30.10.2005.

Bo ni efekti i veze izme u operatora




Bo ni efekti koji postoje kod operatora za primitivne tipove ne podrazumevaju se za preklopljene operatore

bo ni efekti postoje kod:


 

operatora ++ i - (prefiksnih i postfiksnih) svih operatora dodele (=, +=, -=, *=, ...)

Veze koje postoje izme u operatora za primitivne tipove ne podrazumevaju se za preklopljene operatore

na primer, ako je definisan operator+, a+=b ne zna i automatski a=a+b ako je potreban, operator += mora posebno da se preklopi preklopljeni operatori treba da imaju o ekivano zna enje (zbog itljivosti)
 

Preporuke:

na primer, ako su definisani i operator+= i operator+, dobro je da a+=b ima isti efekat kao i a=a+b operatori dodele treba da menjaju stanje levog operanda na primer, ako su definisani operator= i operator+, treba definisati i operator+= za definisan operator== treba definisati i operator!= Preklapanje operatora 30.10.2005.

kada se defini u operatori za klasu, treba te iti da njihov skup bude kompletan
 

Operatorske metode/glob. funkcije




Ako je @ neki binarni operator (na primer +), on mo e da se realizuje:


kao metoda klase X:


 

<tip> operator@(X)
a.operator@(b)

poziv a@b se tuma i kao: poziv a@b se tuma i kao:

kao prijateljska globalna funkcija:

<tip> operator@(X,X)
operator@(a,b)

 

Nije dozvoljeno da se u programu nalaze obe ove funkcije Kod operatorske metode levi operand je skriveni argument

ako levi operand treba da bude standardnog tipa mora se deklarisati globalna prijateljska funkcija u klasi drugog argumenta primer: Complex operator-(double d, Complex c) mora biti prijateljska

Operatorska metoda ne dozvoljava konverziju levog operanda

Preklapanje operatora

30.10.2005.

Primer metode/globalne funkcije


class Complex { double real,imag; public: Complex (double r=0, double i=0) : real(r), imag(i) {} Complex operator+(Complex c) { return Complex(real+c.real,imag+c.imag; } }; class Complex { // alternativno double real,imag; public: Complex (double r=0, double i=0) : real(r), imag(i) {} friend Complex operator+(Complex,Complex); }; Complex operator+ (Complex c1, Complex c2) { return Complex(c1.real+c2.real,c1.imag+c2.imag); } void main () { Complex c1(2,3),c2(3.4); Complex c3=c1+c2; // c1.operator+(c2) ili operator+(c1,c2) }

Preklapanje operatora

30.10.2005.

Unarni i binarni operatori




Unarni operator ima samo jedan operand, pa se mo e realizovati:


kao metoda bez argumenata: tip operator@ () kao globalna funkcija sa jednim argumentom: tip operator@ (X x) kao metoda sa jednim argumentom: tip operator@ (X xdesni) kao globalna funkcija sa dva argumenta: tip operator@ (X xlevi, X xdesni)

Binarni operator ima dva argumenta, pa se mo e realizovati


Preklapanje operatora

30.10.2005.

Primer unarnih i binarnih operatora


class Complex { //... public: // metoda unarni operator! Complex operator!(); // globalna f-ja, unarni operator~ friend Complex operator~(Complex); // metoda binarni operatorComplex operator-(Complex); // globalna f-ja, binarni operator+ friend Complex operator+(Complex,Complex); };

10

Preklapanje operatora

30.10.2005.

Preklapanje new i delete (1)




Mo e se preuzeti kontrola nad alokacijom memorije od ugra enog alokatora

na primer, kada su objekti klase mali, mo e se precizno vr iti njihova alokacija, tako da se smanji re ija alokacije

 

Za ovakve potrebe mogu se preklopiti operatori new i delete za neku klasu Operatorske funkcije new i delete su stati ke (static) metode

ak i ako nisu tako deklarisane, one su stati ke razlog: one se pozivaju pre nego to je objekat stvarno kreiran, odnosno po to je uni ten ne treba eksplicitno pozivati konstruktor, odnosno destruktor konstruktor se implicitno poziva posle operatorske funkcije new destruktor se implicitno poziva pre operatorske funkcije delete obezbede prostor za sme tanje dinami kog objekta (new) oslobode prostor koji je bio alociran za dinami ki objekat (delete)

Unutar tela ovih operatorskih funkcija:


Ove operatorske funkcije slu e samo da:


Operator new treba da vrati pokaziva na alocirani prostor

11

Preklapanje operatora

30.10.2005.

Preklapanje new i delete (2)




Ove operatorske funkcije deklari u se na slede i na in:


void* operator new (size_t velicina) void operator delete (void* pokazivac) slu i za izra avanje veli ina objekata u bajtovima

     

Tip size_t je celobrojni tip definisan u <stddef.h>

Argument velicina daje veli inu prostora koji treba alocirati za objekat Stvarni argument za velicina je sizeof(T), gde je T klasa za koju je preklopljen operator new Stvarni argument se formira na osnovu tipa T u operaciji new T Argument pokazivac je pokaziva na prostor koji treba osloboditi Ako su u klasi T preklopljeni operatori new i delete, ugra eni operatori new i delete mogu da se pozivaju:

eksplicitno, preko operatora :: (::operator new T i ::operator delete pt), ili implicitno, kada se dinami ki kreiraju objekti koji nisu tipa T

 

U slu aju dinami kih nizova objekata uvek se pozivaju globalni new i delete Metode new i delete ne mogu biti virtuelne, ali se nasle uju

12

Preklapanje operatora

30.10.2005.

Primer preklapanja new i delete


#include <stddef.h> class XX { public: void* operator new (size_t { return new char[sz]; } // koristi se ugra void operator delete (void { delete [] p; } // koristi se ugra };

sz) eni new *p) eni delete

13

Preklapanje operatora

30.10.2005.

Inicijalizacija i dodela vrednosti




Inicijalizacija objekta pri kreiranju i dodela vrednosti su razli ite operacije


inicijalizacija podrazumeva da objekat jo ne postoji dodela podrazumeva da objekat sa leve strane operatora ve postoji stati ki, automatski, klasni lan, privremeni i dinami ki konstruktor se poziva ak iako je notacija za inicijalizaciju simbol = ako je izraz sa desne strane = istog tipa kao i objekat koji se kreira, poziva se konstruktor kopije


 

Inicijalizacija se vr i uvek kada se kreira objekat:


Inicijalizacija poziva konstruktor, a ne operator dodele

ovaj konstruktor naj e

e kopira ceo slo eni objekat, a ne samo lanove

 

Dodelom se naziva izvr avanje izraza sa operatorom dodele =

operator dodele se mo e preklopiti pisanjem operatorske funkcije operator= pri kopiranju lanova tipa klase


Podrazumevano zna enje operatora = je kopiranje objekta lan po lan


pozivaju se operatori = klasa kojima lanovi pripadaju kopira e se samo taj pokaziva , a ne i pokazivana vrednost kada treba kopirati i pokazani objekat treba da se preklopi operator=

ako je lan klase tipa pokaziva a


 

14

Preklapanje operatora

30.10.2005.

Preklapanje operatora dodele


 

Operatorska funkcija operator= mora biti nestati ka metoda Operatorska funkcija = se naj e e realizuje tako da:

prvo uni tava prethodno formirane delove objekta, zatim formira nove, uz kopiranje delova objekta sa desne strane = re enje je slede e: X& X::operator=(const X &x){ if (&x != this) { /* uni tava se sadr aj delova starog *this, formira novi i kopira iz x */} return *this; } sva je prilika da treba da sadr i sva tri
Preklapanje operatora 30.10.2005.

Problem se pojavljuje kod izraza a=a

Ako neka klasa sadr i destruktor, konstruktor kopije ili operator=

15

Primer preklapanja operatora =


class String { public: String(const char*); // konstruktor String(const String&); // konstruktor kopije ~String(); // destruktor String& operator=(const String&); // operator dodele private: char *tekst; }; String::String(const String &s) { if (tekst=new char [strlen(s.tekst)+1]) strcpy(tekst,s.tekst); } String::~String() { delete [] tekst; } String& String:operator=(const String &s) { if (&s!=this) { // provera na s=s if (tekst) delete [] tekst; // prvo oslobodi staro, if (tekst=new char [strlen(s.tekst)+1]) strcpy(tekst,s.tekst); // pa onda zauzmi novo } return *this; } void main () { String a("Hello world!"), b=a; // String(const String&); a=b; // operator= }

16

Preklapanje operatora

30.10.2005.

Preklapanje operatora ++ i - 

Problem: postoje prefiksne i postfiksne varijante operatora ++ i -Za preklapanje prefiksnih oblika operatora ++ i --:

koriste se uobi ajene operatorske funkcije:


 

u obliku metode klase T bez argumenata: T operator@@() u obliku funkcije prijatelja klase T sa jednim argumentom: T operator@@(T)

Za preklapanje postfiksnih oblika operatora ++ i --:

operatorska funkcija sadr i i jedan dodatni arument tipa int i to:


 

u obliku metode klase T sa jednim argumentom: u obliku funkcije prijatelja klase T sa dva argumenta:

T operator@@(int) T operator@@(T, int)

 

Ako se postfiksna operatorska funkcija poziva kori enjem operatora @@ argument tipa int ima vrednost 0 Ako se za postfiksnu funkciju koristi notacija t.operator@@(k) ili operator@@(t,k) mo e biti k!=0

17

Preklapanje operatora

30.10.2005.

Preklapanje operatora ()
     

Operator () je binarni operator kojem odgovara funkcija operator()() Operatorska funkcija operator()() mora da bude nestati ka metoda

funkcija operator()() ne mo e da bude globalna prijateljska funkcija proizvoljan broj proizvoljnog tipa f(a1,...,aN) je ekvivalent izrazu f.operator()(a1,...,aN)

Argumenti: Pozivanje: Preklapanje operatora() u nekoj klasi omogu ava izraze sa o(a1,...,aN), gde je o objekat date klase Primer: P p; float x;

ako je P klasa polinoma, mo e se pisati p(x) za vrednost polinoma u x, ako se preklopi funkcija operator()(float)

18

Preklapanje operatora

30.10.2005.

Preklapanje operatora [] (1)


  

Operator [] je binarni operator kojem odgovara funkcija operator[]() Operatorska funkcija operator[]() mora da bude nestati ka metoda

funkcija operator[]() ne mo e da bude globalna prijateljska funkcija kod standardnog indeksiranja indeksni izraz mora biti celobrojnog tipa kod preklopljenog operatora [] indeksni izraz mo e biti proizvoljnog tipa niz[ind] je ekvivalent izrazu niz.operator[](ind) za objekat niz

Argument: Pozivanje:

  

Preklapanje operatora [] u nekoj klasi omogu ava izraze sa o[i], gde je o objekat date klase Mogu e primene:

klasa iji su objekti nizovi sa zadatim granicama indeksa: funkcija indeksiranja mo e da proverava granice asocijativni pristup komponentama niza

19

Preklapanje operatora

30.10.2005.

Preklapanje operatora [] (2)




Ako izraz sa operatorom [] mo e da bude prvi operand operacije =


na primer: o[i]=izraz; tip funkcije operator[]() treba da bude referenca na objekat

Izraz sa preklopljenim operatorom [] nije indeksiranje ve samo notacijski isto izgleda

operatorska funkcija operator[]() dejstvuje na objekat svoje klase, a ne na niz objekata, kao standardni operator []

Prirodno je da struktura objekta bude kolekcija elemenata, a da se operatorom [] odabira neka komponenta

20

Preklapanje operatora

30.10.2005.

Preklapanje operatora ->


    

Operator -> je unarni operator kojem odgovara funkcija operator->() Operatorska funkcija operator->() mora da bude nestati ka metoda

funkcija operator->() ne mo e da bude globalna prijateljska funkcija funkcija operator->() mora biti bez argumenata o->clan je ekvivalent izrazu (o.operator->())->clan treba da bude tipa pokaziva a na klasu koja sadr i clan bude objekat (ili referenca) klase za koju je tako e definisan operator-> pristup lanovima objekata preko "pametnih pokaziva a"

Argumenti: Pozivanje: Rezultat:


Primena:

21

Preklapanje operatora

30.10.2005.

Primer preklapanja operatora ->




Odbrojavaju se indirektni pristupi objektu: struct X{int m}; class Xptr { X *p; int bp; public: Xptr(X *px):p(px),bp(0){} // konstruktor X& operator*() {bp++; return *p;} X* operator->(){bp++; return p;} }; void main(){ X x; Xptr p=&x; // poziva se konstruktor (*p).m=1; // poziva se (p.operator*()).m; int i=p->m; // poziva se (p.operator->())->m; }

22

Preklapanje operatora

30.10.2005.

Preklapanje operatora (tip) (1)


 

Preklapanje cast operatora je drugi na in za konverziju klasnih tipova


prvi na in konverzije korisni kih tipova je pomo u konstruktora funkcija treba da izvr i konverziju objekta klase iji je lan u tip T T mo e da bude standardni, izvedeni (npr. pokaziva ) ili klasni tip funkcija operator T() ne mo e da bude globalna prijateljska funkcija funkcija nema argumente (unarni operator, lan klase) (U)t ili U(t) je ekvivalent izrazu t.operator U() drugi oblik je notacijski isti kao da je u pitanju konstruktor U mogu oblik je i stati ki kast: static_cast<U>(t) tip rezultata funkcije ne sme da bude naveden u deklaraciji/definiciji podrazumeva se na osnovu imena funkcije

Operator (T) je unarni operator kojem odgovara funkcija operator T() Operatorska funkcija operator T() mora da bude nestati ka metoda

  

Argumenti:

Pozivanje:

Rezultat:

23

Preklapanje operatora

30.10.2005.

Preklapanje operatora (tip) (2)




Za razliku od konstruktora U(t) preklopljeni operator U(t)


mo e da se koristi za U koje je standardni tip argument T t mora biti objekat klase, odnosno T ne mo e biti primitivan tip

   

Primer: int(x) - konvertuje x tipa X u tip int Oblik notacije U(t) ne mo e da se koristi za tipove sa ve im brojem re i Primer: (unsigned long) x nije isto to i unsigned long(x) Konverzija se primenjuje automatski, ako je jednozna an izbor konverzije

ako je definisan konstruktor kopije U(T) i operatorska funkcija T::operator U(), u=t je dvozna no ako su definisane obe konverzije U(t) i T(u), prevodilac ne mo e automatski da odredi konverziju za u+t rezultat konverzije stvarnog argumenta je privremeni objekat, pa se u funkciju prenosi njegova adresa izmene u funkciji se odnose na taj privremeni objekat

Problem sa konverzijom tipa pri prenosu parametara po referenci


24

Preklapanje operatora

30.10.2005.

Standardni U/I tokovi


    

Kao ni jezik C, ni C++ ne sadr i ugra ene U/I naredbe

one se realizuju standardnim bibliotekama

Za C++ postoje standardne U/I biblioteke realizovane u duhu OOP-a Na raspolaganju su i stare C biblioteke sa funkcijama scanf i printf

njihovo kori

enje nije u duhu C++ i treba izbegavati

Deklaracije C++ biblioteke za U/I nalaze u zaglavlju <iostream.h> Biblioteka iostream sadr i dve osnovne klase za U/I:

istream (apstrakcija ulaznog toka) ostream (apstrakcija izlaznog toka) objektu klase ifstream/ofstream mo e da se pridru i jedna datoteka za U/I odnosno funkcija lanica ili prijatelja ovih klasa

 

Iz navedenih klasa su izvedene klase ifstream i ofstream


Datotekama se pristupa isklju ivo preko ovakvih objekata

25

Preklapanje operatora

30.10.2005.

Standardni objekti i operacije za U/I




U biblioteci iostream definisana su i dva globalna stati ka objekta:


objekat cin klase istream


 

koji je pridru en standardnom ulaznom ure aju (obi no tastatura) koji je pridru en standardnom izlaznom ure aju (obi no ekran)

objekat cout klase ostream

Klasa istream je preklopila operator>> za sve ugra ene tipove, koji slu i za ulaz podataka:

istream& operator>>(istream &is, T &t); gde je T neki ugra eni tip objekta koji se ita

Klasa ostream je preklopila operator<< za sve ugra ene tipove, koji slu i za izlaz podataka:

ostream& operator<<(ostream &os, const T& x); gde je T neki ugra eni tip objekta koji se ispisuje

26

Preklapanje operatora

30.10.2005.

Kori


enje operatora >> i <<

Operatorske funkcije operator>> i operator<<


vra aju referencu na levi operand
 

posledica: mo e se vr iti vi estruki U/I u istoj naredbi posledica: podaci se ispisuju/u itavaju u prirodnom redosledu

operatori su asocijativni sleva

 

Operatore >> i << treba koristiti za jednostavne U/I operacije Primer:


#include <iostream.h> void main () { int i; cin>>i; cout<<"i="<<i<<endl; }

27

Preklapanje operatora

30.10.2005.

Preklapanje operatora >> i <<


  

Korisnik mo e da defini e zna enja operatora >> i << za svoje tipove


to se posti e definisanjem odgovaraju ih globalnih funkcija prijatelja date klase prvi operand je tipa istream& odnosno ostream&

Razlog zbog kojeg preklopljen operator ne mo e biti metoda: Primer za klasu Complex: #include <iostream.h> class Complex { double real,imag; friend ostream& operator<< (ostream&,const Complex&); public: //... kao i ranije }; ostream& operator<< (ostream &os, const Complex &c) { return os<<"("<<c.real<<","<<c.imag<<")"; } void main () { Complex c(0.5,0.1); cout<<"c="<<c<<endl; // ispisuje se: c=(0.5,0.1) }
Preklapanje operatora 30.10.2005.

28

You might also like