460 likes | 815 Views
Objektno orijentisano programiranje. Preklapanje operatora. Preklapanje operatora. Tipovi operatora Tipovi podataka i efekat operatora Pojam preklapanja operatora Operatorske funkcije Konverzije tipova. Ugra đeni o peratori (C#). Upotreba operatora za skraćivanje pisanja izraza.
E N D
Objektno orijentisano programiranje Preklapanje operatora
Preklapanje operatora • Tipovi operatora • Tipovi podataka i efekat operatora • Pojam preklapanja operatora • Operatorske funkcije • Konverzije tipova
Zašto se koriste operatori? • Korišćenjem operatora • Bez operatora, korišćenjem metoda Matrix a, b, c; Matrix d = c * (a + b); Matrix a, b, c; Matrix d = c.Multiply(a.Add(b));
Tipovi podataka (C#) • Dvije kategorije tipova • Value types • Prosti tipovi (int, byte, float...) i strukture • Direktno sadrže vrijednost • Vrijednost se čuva u stack dijelu memorije • Reference types • Klasni tipovi • Sadrže referencu na vrijednost (adresu memorijske lokacije) • Vrijednost se čuva u managed heap dijelu memorije • Zavisno od kategorije tipa, razlikuje se način izvršavanja operacija nad podacima tog tipa
CTS (Common Type System) Type Value Type Reference Type
Value Types Value Types Built-in Type User-Defined • int • float • enum • struct
Value Types - primjer // i, j su tipa int i = 20; j = i; i++; j+=2; Console.WriteLine(i); Console.WriteLine(j); • Koje vrijednosti se ispisuju?
Reference Types • Kreiranje varijabli coordinate c1; c1 = new coordinate(); c1.x = 6.12; c1.y = 4.2; • 6.12 4.2 • Uklanjanje reference c1 = null; • 6.12 4.2
Više referenci na isti objekat • c1 2.3 7.6 c2 • coordinate c1= new coordinate( ); coordinate c2; c1.x = 2.3; c1.y = 7.6; c2 = c1; Console.WriteLine(c1.x + " , " + c1.y); Console.WriteLine(c2.x + " , " + c2.y);
Poređenje vrijednosti i referenci • Poređenje Value tipova • Operatori “==“i“!=“porede vrijednosti • Poređenje Reference tipova • Operatori “==“i“!=“porede reference, ne porede vrijednosti • 1.0 2.0 Dvije različite reference na iste vrijednosti • 1.0 2.0
Reference Types - primjer //Vektor je klasa koja posjeduje javni atribut Vrijednost Vektor x, y; x = new Vektor(); x.Vrijednost= 30; y = x; Console.WriteLine(y.Vrijednost); y.Vrijednost = 50; Console.WriteLine(x.Vrijednost); • Koje vrijednosti se ispisuju?
Poređenje jednakosti objekata • Način poređenja zavisi od tipa objekta, odnosno da li je Value ili Reference tipa • Kod varijabli koje su Value tipa (prosti tipovi, instance struktura ili nabrojanja) porede se vrijednosti • Kod varijabli koje su Reference tipa (klasni tipovi, instance klasa) porede se reference, odnosno adrese memorijskih lokacija
Načini poređenja (C#) • System.Object, nekoliko metoda poređenja • ReferenceEquals() • Ispituje da li su dvije reference iste, tj da li pokazuju na istu instancu objekta u memoriji • Nema smisla da se koristi za Value tipove • Equals() • Poredi reference za Reference tipove, može se predefinisati za korisničke klase • Poredi vrijednosti za Value tipove • Operator poređenja (==) • Za Reference tipove poredi reference, može se predefinisati • Za Value tipove poredi vrijednosti, potrebno ga je redefinisati za korisničke tipove (strukture)
Pojam preklapanja operatora • Preklapanje operatora (operator overloading) • predstavlja redefinisanje postojećih operatora zbog potrebe da na specifičan način rade sa novim tipovima podataka (npr. klasnim tipovima) • omogućava da se ugrađeni operatori prilagode tako da izvršavaju određenu akciju nad objektima klasnih tipova
Pojam preklapanja operatora • Moguće je izvršiti preklapanje skoro svih operatora • Preklapanjeoperatora treba pažljivo koristiti, zbog mogućih neželjenih efekata • Primjeri korištenja preklapanja operatora kod ugrađenih tipova • operator dodjele se koristi na isti način za različite tipove podataka • operator sabiranja se koristi i za cijele i za realne brojeve
Pojam preklapanja operatora • Za korištenje operatora nad objektima klasnih tipova u opštem slučaju potrebno je preklapanje operatora • Preklapanje se vrši tako što se definiše operatorska funkcija • Operatorske funkcije se implementiraju: • kaometode • kao globalne funkcije, obično prijateljske funkcije klasa (C++)
Primjer preklapanja operatora • Pretpostavimo da su u programu potrebni kompleksni brojevi i operacije nad njima. • Tip kompleksnog broja će realizovati klasa koja sadrži elemente (real, imag), a takođe i funkcije za operacije. • Pogodno je da se pozivi funkcija koje realizuju operacije mogu notacijski predstaviti standardnim operatorima. • U jezicima C#/C++, operatori za korisničke tipove (klase) su specijalne operatorske funkcije. • Operatorske funkcije nose ime operator@, gde je @ neki operator ugrađen u jezik. • Operatorske funkcije preklapaju standaradne operatore (+, -, *, /, ...).
Operatorske funkcije • Operatorske funkcije se mogu koristiti u izrazima kao i operatori nad ugrađenim tipovima. • Ako je operatorska funkcija definisana na prethodno opisan način, izraz t1@t2 se tumači kao operator@(t1,t2):
Primjer (C#) • struct Vector • { • public double x, y, z; • public Vector(Vector rhs) • { • x = rhs.x; • y = rhs.y; • z = rhs.z; • } • public static Vector operator + (Vector lhs, Vector rhs) • { • Vector result = new Vector(lhs); • result.x += rhs.x; • result.y += rhs.y; • result.z += rhs.z; • return result; • } • }
Osnovna pravila preklapanja operatora • C#/C++ dozvoljava preklapanje operatora kao što dozvoljava i preklapanje imena funkcija. • Princip preklapanja omogućava da se definišu nova značenja operatora za korisničke tipove.
Osnovna pravila preklapanja operatora • Postoje neka ograničenja u preklapanju operatora: • ne mogu direktno da se preklope svi operatori, neki ne mogu nikako; • 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 mijenjaju osobine operatora koje su ugrađene u jezik: n-arnost, prioritet i asocijativnost.
Operatorske funkcije kao članice ili kao globalne funkcije (C++) • Ako je @ neki binarni operator (npr +), on može da se realizuje: • Kao funkcija članica klase X • Kao prijateljska globalna funkcija • Nije dozvoljeno da se u programu nalaze obje ove funkcije
Operatorske funkcije kao članice(C++) <tip> operator@ (X) Poziv a@b se sada tumači kao: a.operator@(b) , za funkciju članicu
Operatorske funkcije kao prijateljske funkcije (C++) <tip> operator@ (X,X) Poziv a@b se sada tumači kao: operator@(a,b) , zaglobalnu funkciju
Unarni i binarni operatori(C++) • Unarni operator ima samo jedan operand, pa se može realizovati: • kao operatorska funkcija članica bez argumenata: tip operator@ () • kao globalna funkcija sa jednim argumentom: tip operator@ (X x) • Binarni operator ima dva argumenta, pa se može realizovati: • kao funkcija članica sa jednim argumentom: tip operator@ (X xdesni) • kao globalna funkcija sa dva argumenta: tip operator@ (X xlevi, X xdesni)
Preklapanje unarnih operatora(C++) • Unarni operator može biti preklopljen kao: • nestatička funkcija članica bez argumenata; ne može biti statička jer mora pristupati pojedinačnom atributu • samostalna funkcija (nije funkcija članica) sa jednim argumentom (objekat ili referenca)
Preklapanje binarnih operatora(C++) • Binarni operator može biti preklopljen kao: • nestatička funkcija članica sa jednim argumentom • samostalna funkcija sa dva argumenta (bar jedan mora biti objekat ili referenca na objekat)
Preklapanje operatora u C# • Operatorske funkcije realizuju se kao funkcije članice klasa • Operatorske funkcije se definišu kao javne i statičke metode klasa • Ne mogu koristiti pokazivač this na objekat date klase • Imaju jedan argument za unarne, dva za binarne operatore • Najmanje jedan argument mora biti korisnički definisan tip (klasa, struktura)
Preklapanje aritmetičkih operatora (C#) public static Vector operator + (Vector lhs, Vector rhs) { Vector result = new Vector(lhs); result.x += rhs.x; result.y += rhs.y; result.z += rhs.z; return result; } public static Vector operator * (double lhs, Vector rhs) { return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z); } public static double operator * (Vector lhs, Vector rhs) { return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z; }
Preklapanje relacionih operatora (C#) • Postoji 6 relacionih operatora u jeziku C# i moraju se preklapati u parovima • == i != • > i < • >= i <= • Ako se izvrši preklapanje operatora ==, mora se preklopiti i operator !=, u protivnom kompajler prijavljuje grešku • Slično važi za ostale relacione operatore • Relacioni operatori vraćaju logičku vrijednost
Preklapanje relacionih operatora (C#) • Ako se izvrši preklapanje operatora == i !=, moraju se predefinisati i funkcije Equals() i GetHashCode()naslijeđene iz System.Object • Funkcija Equals() treba da implementira istu logiku kao i operator jednakosti • Ako se ne izvršti redefinisanje prethodne dvije metode, kompajler generiše upozorenje (ne grešku)
Primjer (C#) public static bool operator == (Vector lhs, Vector rhs) { if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z) return true; else return false; } public static bool operator != (Vector lhs, Vector rhs) { return ! (lhs == rhs); }
Konverzija tipova • Implicitna konverzija • Izvršava se automatski između kompatibilnih tipova upotrijebljenih u izrazima • Eksplicitna konverzija • Kada postoji rizik gubitka podataka ili pojave greške u konverziji • Mora se eksplicitno navesti u izrazu • Cast operator (tip) se koristi za eksplicitnu konverziju tipova • Sintaksa: (tip)varijabla int i= 3; long j= i; // implicitna short s = (short)i; // eksplicitna
Konverzije korisnički definisanih tipova u C# • Konverzija se definiše kao operatorska funkcija u okviru klase • Može se definisati kao implicitna ili eksplicitna konverzija • Uvijek definisati kao eksplicitnu konverziju u slučaju da postoji bilo kakva mogućnost greške pri konverziji • Povratni tip operatorske funkcije jednak je operatoru konverzije public static implicit operator float (Currency value) { return value.Dollars + (value.Cents/100.0f); }
Primjer – implicitna konverzija (C#) //primjer definisanja operatora konverzije za slučaj struktura //na isti način se radi sa klasama structCurrency { public uint Dollars; public ushort Cents; public static implicit operator float (Currency value) { return value.Dollars + (value.Cents/100.0f); } } ... Currency balance = new Currency(10,50); float f = balance; //implicitna konverzija Currency u float
Primjer – eksplicitna konverzija (C#) struct Currency { public uint Dollars; public ushort Cents; } public static explicit operator Currency (float value) { uint dollars = (uint)value; ushort cents = (ushort)((value-dollars)*100); return new Currency(dollars, cents); } } .... float amount = 45.63f; Currency amount2 = (Currency)amount; //eksplicitna konverzija Currency amount3= amount; // greška
Konverzije između klasa (C#) • Moguće je definisati konverzije između bilo koja dva korisnički definisana tipa (klase, strukture) • Ograničenja • Ne može se definisati konverzija za dvije klase ako je jedna izvedena iz druge klase • Konverzija se mora definisati u okviru definicije izvorišne ili odredišne klase (tipa)
Primjer (C#) • Moguće je definisati konverziju samo između klasa C i D • Operatorska funkcija za konverziju se definiše u okviru definicije klase C ili D, ne u obje • Mora biti moguć pristup source kodu klasa C ili D da bi se realizovala konverzija Ograničenja Hijerarhija klasa
Primjer (C#) public static explicit operator D(C value) { //implementacija konverzije } public static explicit operator C(D value) { //implementacija konverzije }