1 / 38

Vrednosni i referentni tipovi

Int, float, double, char su tzv. prosti ili ugrаđeni tipovi podataka koji se još sa aspekta načina rada sa tim podacima zovu i vrednosni tipovi (value type) Objekti predstavljaju drugu vrstu podataka koji se za razliku od pomenutih vrednosnih tipova nazivaju referentni tipovi (reference types)

cybill
Download Presentation

Vrednosni i referentni tipovi

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Int, float, double, char su tzv. prosti ili ugrаđeni tipovi podataka koji se još sa aspekta načina rada sa tim podacima zovu i vrednosni tipovi (value type) • Objekti predstavljaju drugu vrstu podataka koji se za razliku od pomenutih vrednosnih tipova nazivaju referentni tipovi (reference types) • Suštinska razlika u tretmanu između ova dva tipa nastaje još u postupku kreiranja podataka • Pomenuti prosti tipovi se kreiraju deklaracijom promenljive, čime se u memoriji rezerviše prostor za smeštanje vrednosti deklarisanog vrednosnog tipa Vrednosni i referentni tipovi

  2. int i = 42; // declare and initialize i • Ako se deklariše još jedna int promenljiva – copyi i inicijalizuje sa vrednošću od i, nastaje kopija vrednosti od i na drugoj memorijskoj lokaciji • int copyi = i; // copyi contains a copy of the data in i • i++; // incrementing i has no effect on copyi • Promena jedne od ovih vrednosti nema nikakvog uticaja na onu drugu vrednost, tj. različite vrednosne promenljive su sasvim nezavisne • Za razliku od toga, referentni tipovi se ponašaju sasvim drugačije Vrednosni i referentni tipovi

  3. Kada se kreira objekat, neophodno je da se izvrši deklaracija objektne promenljive, tj. promenljive preko koje će se pristupati podacima i metodama članicama tog objekta • Circle c = new Circle(42); • Circle je naziv klase, dok je c objektna promenljiva • Deklaracijom Circle c se rezerviše memorija ne za čitav objekat, nego samo za pokazivač / adresu / referencu koja će pokazivati na adresu na kojoj je objekat zaista smešten • Memorija za objekat tipa Circle se kreira sa new čime se aktivira konstruktor (koji vrši inicijalizaciju) i vraća se referenca / adresa na novokreirani objekat koja se dodeljuje objektnoj promenljivoj - c Vrednosni i referentni tipovi

  4. Ako se kao i u prethodnom slučaju kreira još jedna objektna promenljiva - refc i inicijalizuje se sa vrednošću c, onda se dešava suštinski drugačija vrsta dodele nego u slučaju običnih vrednosnih tipova • Circle refc = c; • Pošto su c i refc objektne promenljive, tj. pokazivači ili reference na sam objekat koji se nalazi na sasvim drugom mestu u memoriji, onda se dodelom refc=c u stvari dešava to da posle dodele i c i refc pokazuju na isti objekat u memoriji, tj. sadrže istu adresu Vrednosni i referentni tipovi

  5. Navedene razlike vrednosnih i referentnih tipova su prikazane na sledećim slikama Vrednosni i referentni tipovi

  6. Prethodni postupak dodele vrednosti kod referentnih tipova je u terminologiji C++ - a poznat kao tzv. plitka kopija. Direktnom dodelom se pravi plitka kopija. Duboka kopija bi podrazumevala kreiranje dva odvojena objekta u memoriji sa istim vrednostima podataka članova na koje bi posebno pokazivali c i refc, tj. c bi pokazivao na jedan objekat a refc na drugi objekat. • Opisana razlika kod vrednosnih i referentnih tipova ima mnoge važne posledice, na pr. razlika kod predaje argumenata metodima, gde argumenti mogu biti vrednosni ili referentni tipovi Vrednosni i referentni tipovi

  7. Podrazumevani prenos parametara u metodima je po vrednosti (by value) • To znači da se pravi kopija argumenta koji se predaje u pozivu metoda • Metod dobija kopiju koja je nezavisna od predatog originala • Promenom vrednosti koja je dobijena kao argument, original se ne menja • U velikom broju slučajeva to je i željeno ponašanje • Razlikuju se prenos po vrednosti vrednosnih i referentnih tipova argumenata • Kod vrednosnih tipova, kao što je i rečeno, pravi se kopija vrednosti argumenta koja se koristi u metodi Prenos parametara metoda po vrednosti i referenci

  8. Prenos parametara metoda po vrednosti i referenci • Kod referentnih tipova, takođe se pravi kopija vrednosti argumenta, ali ta kopija sada predstavlja adresu koja ukazuje na sam objekat. • Na taj način, metod ima adresu originala i sve operacije sa objektom se vrše na originalu. Ažurirane vrednosti podataka članova objekta su dostupne i iz procedure koja je pozvala metod. • Dakle, kada se referentni tipovi prenose po vrednosti kao argumenti, onda se prenosi adresa po vrednosti, što znači da je dostupan original objekta. • To je prikazano na sledećoj slici

  9. Prenos parametara metoda po vrednosti i referenci • WrappedInt je naziv korisničke klase koja kao jedini podatak član sadrži podatak Number tipa int. • Pass je takođe korisnička klasa koja ima samo dva metoda člana – Value i Reference kojima se ilustruje prenos argumenata

  10. Prenos parametara metoda po vrednosti i referenci • class Program • { • static void Entrance() • { • int i = 0; • Console.WriteLine(i); • Pass.Value(ref i); • Console.WriteLine(i); • WrappedInt wi = new WrappedInt(); • Console.WriteLine(wi.Number); • Pass.Reference(wi); • Console.WriteLine(wi.Number); • }

  11. Null vrednosti i Nullable tipovi • Inicijalizacija vrednosnih tipova: • int i = 0; • double d = 0.0; • Referentni tipovi se inicijalizuju pri kreiranju novog objekta u memoriji sa new: • Circle c = new Circle(42); • Circle copy = new Circle(99); // Some random value, for initializing copy • ... • copy = c; // copy and c refer to the same object • Šta se dešava sa objektom koji je inicijalizovan sa 99 i na koji je pokazivao copy? • Ništa, taj objekat je izgubljen, jer nema pokazivača na njega • Šta se dešava sa izgubljenim objektom – na koji više ne pokazuje nijedan pokazivač? • Garbage colector ga briše iz memorije, ali se tačno ne zna kada se to dešava

  12. Null vrednosti i Nullable tipovi • Circle c = new Circle(42); • Circle copy; // Uninitialized !!! • ... • if (copy == // what goes here?) • copy = c; // copy and c refer to the same object • Ako referenci copy treba da se dodeli objekat na koji pokazuje c, onda ne treba referenci copy dodeljivati objekat sa new pri deklaraciji. • Kako onda inicijalizovati copy tako da se zna da još uvek ne sadrži valid objekat?

  13. Vrednost null i nullable tip • Circle c = new Circle(42); • Circle copy = null; // Initialized • ... • if (copy == null) • copy = c;// copy and c refer to the same object • Vrednost null se može dodeliti bilo kom referentnom tipu u cilju regularne inicijalizacije • Null vrednosti se ne mogu dodeliti vrednosnim tipovima • int i = null; // illegal • Sa modifikatorom ? se može označiti da se regularno dodeljuje null vrednosnom tipu koji postaje nullable tip • int? i = null; // legal

  14. Vrednost null i nullable tip • Provera da li nullable tip sadrži vrednost null • if (i == null) • ... • int? i = null; • int j = 99; • i = 100; // Copy a value type constant to a nullable type • i = j; // Copy a value type variable to a nullable type • Tipu nullable - i se može dodeliti obična vrednost j, ali ne i obrnuto – vrednosnom tipu j nullable vrednost i • j = i; // Illegal • int? i = 99; • Pass.Value(i); // Compiler error

  15. Properties – svojstva nullable tipova • HasValue i Value svojstva nullable tipova • int? i = null; • ... • if (!i.HasValue) • i = 99; • else • Console.WriteLine(i.Value);

  16. Predavanje argumenata po referenci • static void DoWork(ref intparam) // using ref • { • param++; • } • static void Main() • { • intarg = 42; • DoWork(ref arg); // using ref • Console.WriteLine(arg); // writes 43 • } • Sa ref u definiciji metoda i pozivu metoda se naznačava da se predaje referenca a ne kopija vrednosti

  17. Početna vrednost • static void DoWork(ref intparam) • { • param++; • } • static void Main() • { • intarg; // not initialized • DoWork(ref arg); • Console.WriteLine(arg); • } • Ne može se predati argument ukoliko nije inicijalizovan • Ali, ipak postoji mogućnost...

  18. Out parametri • Out slično kao i ref označava da se parametri predaju po referenci, ali još dodatno omogućava da se preda neinicijalizovan argument pri pozivu procedure • static void DoWork(out intparam) • { • // Do nothing • } • Out zahteva da metoda postavi vrednost argumenta • static void DoWork(out intparam) • { • param = 42; • }

  19. Poziv metode sa out • static void Main() • { • int arg; // not initialized • DoWork(out arg); • Console.WriteLine(arg); // writes 42 • } • I vrednosni i referentni tipovi se mogu predati po vrednosti i po referenci • Za referentne tipove na prvi pogled nema razlike da li se predaju po vrednosti ili referenci – original objekta je dostupan i u jednom i u drugom slučaju • Ima li onda razlike?

  20. Razlika u pozivu procedure sa referentnim tipovima po vrednosti i referenci • Referentni tipovi bilo da su predati metodi po referenci ili po vrednosti uvek omogućavaju pristup originalnom objektu iz metode koja se poziva • Ali, ako je predata po vrednosti, sama objektna promenljiva ne može da se menja, tj. ako se unutar pozvane metode promeni tako da pokazuje na neki drugi objekat, to neće imati uticaja na argument van pozvane metode. • Ako se referentni tip preda po referenci, onda se unutar pozvane procedure može promeniti tako da pokazuje na neki drugi objekat, a da se ta promena vidi i izvan pozvane metode

  21. Organizacija memorije • Memorija koju koristi C# se sastoji od stack (stog) i heap (hrpa, gomila) memorije • Stack memorija se koristi za smeštanje argumenata i lokalnih promenljivih pri pozivu metode • Postoji izvesna analogija stack memorije i naslaganih tanjira u smislu da se novi podaci kao i tanjiri stavljaju odozgo, kao i da se uvek uzimaju odozgo • Vrednosni tipovi se u potpunosti čuvaju na stack-u • Kod referentnih tipova deklarisani pokazivači – objektne promenljive se čuvaju na stack-u, dok se sami objekti na koje pokazuju promenljive na stack-u koji se kreiraju sa new, nalaze u tzv. heap (hrpa, gomila) memoriji

  22. Organizacija memorije • Heap memorija je konačna, i ako nema mesta, dobija se OutOfMemoryException i objekat se ne kreira • Kada se metoda završi, sve lokalne promenljive i argumenti te metode sa stack-a se brišu

  23. Klasa System.Object • Object je klasa u imenskom prostoru System. • Sve klase potiču od ove osnovne sistemske klase, tj. nasleđuju od te klase. • Alias – drugo ime za System.Object se naziva object – ključna reč u C#-u. • Promenljiva tipa object može da pokazuje na objekat bilo kog tipa • Circle c; • c = new Circle(42); • object o; • o = c;

  24. Klasa System.Object

  25. Boxing • Tip object se može primeniti i na vrednosne tipove što se naziva boxing – kreiranje objekta na stack-u • int i = 42; • object o = i;

  26. Unboxing • int i = 42; • object o = i; // boxes • int i = o; //ne može • i = (int)o; // compiles okay – unboxing

  27. Type cast – promena tipa • Circle c = new Circle(42); • object o = c; // doesn’t box because Circle is a reference variable • int i = (int)o; // compiles okay but throws an exception at run time

  28. Is operator • Pri type casting-u, kompajliranje prolazi nezavisno od navedenih tipova, ali se zato u vreme izvršavanja - run time, vrši provera, i dobijaju se poruke o grešci ako stvarni tipovi ne odgovaraju navedenim tipovima • Operator is se koristi za proveru tipova u vreme izvršavanja • WrappedInt wi = new WrappedInt(); • ... • object o = wi; • if (o is WrappedInt) • { • WrappedInt temp = (WrappedInt)o; // This is safe; o is a WrappedInt • ... • }

  29. As operator • WrappedInt wi = new WrappedInt(); • ... • object o = wi; • WrappedInt temp = o as WrappedInt; • if (temp != null) • ... // Cast was successful • Operator as slično kao i is ima iste argumente – levi je objekat a desni tip • Ako se objekat slaže sa tipom tj. ako je casting uspešan, vraća se vrednost navedenog tipa, koja se može dodeliti nekoj promenljivoj – temp, a u slučaju neslaganja vraća se vrednost null

  30. C++ pokazivači i unsafe code • int *pi; • int i = 99; • ... • pi = &i; • *pi = 100; • public static void Main(string [] args) • { • int x = 99, y = 100; • unsafe • { • swap (&x, &y); • } • Console.WriteLine(“x is now {0}, y is now {1}”, x, y); • }

  31. C++ pokazivači i unsafe code • public static unsafe void swap(int *a, int *b) • { • int temp; • temp = *a; • *a = *b; • *b = temp; • }

More Related