Sintaksa strukture je:

Struct ime_strukture 
{
       članovi_strukture;
};

Članovi strukture mogu imati pored promenjivih i metode pa čak i konstruktore.

Struktura ne može da sadrži druge strukture ili klase.

Vi ne možete imati konstruktor u strukturi koji ne uzima ni jedan parametar. On već postoji i implicitno inicijalizuje na nulu sva polja u strukturi.

Vi ne morate da koristite ključnu reč new da instancirate članove strukture ali nije zabranjeno.


Razlike između klase i strukture

Podaci su članovi klase ili strukture.

Klasa je referentni tip. Kada se kreira objekat klase, promenljiva kojoj je dodeljena u sebi sadrži u stvari pokazivač na njoj dodeljen prostor u memoriji.

Struktura je vrednosni tip. Kada se kreira struktura, promenljiva kojoj je dodeljena sadrži stvarne podatke.

Često pitanje u OOP načinu programiranju jeste koja je zapravo razlika između strukture i klase.

Prvo ću krenuti sa strukturom, struktura u C# programskom jeziku je value type što znači da se njena alokacija se uvek nalazi na steku (stack).
Klasa za razliku od strukture svoju alokaciju ima na heap-u tj. u dinamičkoj dijelu memorije, u potpuno drugom logičkom djelu memorije u odnosu na stek.

U primeni, strukturu ćemo najčešće naći kada radimo sa manjim tipovima podataka i manjim količinama podataka, glavni razlog ove "odluke" jeste taj što ona uveliko utiče na performanse naše App (aplikacije). Ako se vodimo predhodno naučenim pojmom čuvanja strukture na steku, imamo pojavu da kada želimo poslati strukturu u neku od funkcija, mi zapravo tada šaljemo čitavu strukturu i njen sadržaj. Iz ovog možemo zaključiti da u runtime-u imamo proces kompletnog kopiranja objekta onoliko puta koliko pozivamo funkcija koje kao parametar preuzimaju našu strukturu. Računica i zaključak je jednostavan: u slučaju veće strukture imamo mnogo veće vreme izvršavanja koje uglavnom ide na kopiranje svih informacija iz strukture u njenu lokalnu kopiju.

Važno za napomenuti je: da je stek mnogo manja logička količina memorija u odnosu na heap, i proces slanja strukture kroz funkcije duplo povećava zauzeće memorije na steku. Još jedna bitna stvar je da u funkciji mi radimo sa kopijom objekta koji je poslat pri pozivu funkcije i svaku promenu koju želimo raditi moramo na adekvatan način uraditi i na "glavnom" objektu.

Kada uzmemo u obzir čitav proces kopiranja shvatimo koliko je ovo "skupo" za našu App... Ako ovaj isti primer primenimo na klase koje su reference type, iz jednog mini testa koji ćemo uraditi u sledećim koracima...dolazimo do zaključka da se klase uvek šalju po referenci tj. u funkciju koja prima našu klasu mi šaljemo adresu našeg objekta u dinamičkoj memoriji i samim tim mi nemamo potrebu za kopiranjem onoga što se nalazi u klasi, a sa ugla performansi šaljemo mnogo manju informaciju (za razliku do strukture i slanja čitavog objekta). Kada prosledimo adresu (referencu) mi u funkciji direktno pristupamo toj memorijskoj lokaciji i radimo potrebne izmene nad našim objektom.

Malo objašnjenje za predhodne pojmove u slučaju da nisu jasne stvari oko adresa. Svaki vaš objekat koji je smešten u memoriji ima svoju memorijsku adresu tj. lokaciju na kojoj se nalazi. Kada vi imate informaciju tj. adresu na kojoj je vaš objekat vi imate "pravo" i mogućnost da ga direktno editujete... mnogo će biti jasnije u sledećem primeru:

Na slikama ispod vidite kako izgleda naša struktura pod imenom "TackaKoordinateStruktura", njeni atributi i konstruktor:


kao i kod na kojem je definisana naša klasa "TackaKoordinateKlasa", atributi i konstruktor:


Kao što i vidite skoro da su identične, jedina razlika na prvi pogled je u ključnim rečima class i struct. Ali naravno velika je razlika u pozadini, a to ćemo upravo dokazati na sledeći način:

Za potrebu ovoga mini testa koristit ćemo dve funkcije koje kao parametar primaju strukturu i klasu, naravno jedna prima strukturu, a druga klasu i izgledaju ovako:


A u main funkciji imamo sledeću situaciju:


Ako pokrenemo naš program možemo očekivati sledeći ispis na konzoli:


Ako pažljivo pratimo ispis na konzoli, možemo primetiti da se vrednost atributa naše strukture promeni samo u funkciji PromjenaStanjaStrukture(), kada se završila funkcija u mainu imamo informaciju da je vrednost atributa strukture ista kao i pre poziva. Iz ovoga možemo zaključiti samo jedno, da je naša struktura po svojoj prirodi poslata u funkciju po vrednosti i da smo u funkciji radili i vršili promene sa njenom kopijom koja je naravno uništena pri završetku funkcije (silazak sa steka).

Sa druge strane ako posmatramo ponašanje naše klase, pri inicijalizaciji je dobila vrednosti (7, 12), te u funkciji PromjenaStanjaKlase(), kao što je i definisano dobija vrednosti (20, 7), posle završetka sledi ispis koji nam ispisuje one vrednosti koje je klasa dobila u funkciji. Objašnjenje ovoga je da se klase uvek šalju po referenci, a ne po vrednosti kao što to strukture rade. Funkcija PromjenaStanjaKlase() dobila je adresu naše klase i mogla je direktno da utiče na promenu njenih atributa tj. modifikovali smo originalni objekat.

Iz ovog mini testa i primera dokazali smo i zaključili da se strukture uvijek šalju po vrednosti, a klase po referenci i ovo nam ujedno i govori pravu razliku između strukture i klase u C# programskom jeziku.

Last modified: Monday, 19 October 2020, 5:24 PM