2010. július 30., péntek

Struktúra vagy osztály?

Azon programozási nyelveknél, amelyeknél létezik struktúra (struct) és osztály (class) típus is, időről-időre talán felvetődik az a kellemes kérdés, hogy vajon adott helyzetben az egyiket, vagy inkább a másikat kellene-e használni? Itt most elsősorban olyan helyzetekre (feladatokra) gondoltam, amelyekhez egyébként bármelyik típus megfelelő lenne (mondjuk azért, mert mindkettőnek lehet adattagja, metódusa, konstruktora, blabla...), de valamilyen oknál fogva nekünk mégis le kell tennünk a voksunkat az egyik mellett. Izgalmas kérdés, vizsgáljuk meg hát a dolgot .NET környezetben.
Sok apró különbség van a struct és class között, de az apróságokat most hagyjuk másra. Az első komolyabb eltérés az, hogy a class öröklődhet (egyik a másikból ugyebár), míg a struct nem. Ez tehát eleve döntő szempont lehet akkor, ha egy hierarchiát, vagy objektum-orientált tulajdonságokkal rendelkező struktúrát kell felépítenünk, mivel így ehhez a feladathoz csakis a class jöhet szóba.
A másik alapvető különbség az, hogy míg a class referencia (reference), addig a struct érték (value) típus. Na, ez már valami! A .NET-ben a referencia típusok a heap-en foglalnak helyet, és a már felesleges példányok eltakarításával a szemétgyűjtő (garbage collector) van megbízva. A szemétgyűjtő nem fut (nem takarít) állandóan, csak akkor, ha úri kedve úgy tartja, vagy inkább... amikor eljött az ideje. Ezzel ellentétesen az érték típusok a stack-en (veremben) tárolódnak, és az élettartamuk addig tart, amíg az adott típus hatóköre tart (pl.: egy függvény elejétől a végéig). Amint megszűnik a hatóköre, azonnal eltűnik a stack-ről, és hmmm... legalábbis nem foglal fizikailag helyet tovább.
Érték típussal általában nem annyira költséges dolgozni, mint referencia típussal egészen addig, amíg becsomagolásra vagy kicsomagolásra nem kerül sor. A becsomagolás (boxing) az, amikor egy érték típust átalakítunk referencia típussá (pl.: egy int belekerül egy object-be), a kicsomagolás (unboxing) pedig ennek a fordítottja. Csomagoláskor tehát az érték típus (vagyis a struct) költségesebb, mint az osztály (vagyis a class), mert - hogy a jelen példára alapozzak - egyszerűen több munka van vele.
Általában elmondható még az is, hogy érdemesebb class-t használni akkor, ha annak a memóriafoglalása (footprint) 16 bájt alatti, illetve a belőle létrehozott példány állapota (tartalma) nem módosul. Szóval akkor most struktúra vagy osztály? A válasz, mint látjuk: attól függ.

Put About

***

Soci jelezte nekem, hogy ez az írásom pontosítást igényel. Örülök, hogy felhívta rá a figyelmemet, és ezennel szeretném egy az egyben közzé tenni az általa írt kiegészítés szövegét: "A value typeok vermen laknak, ha lokális változóként példányosítjuk őket, de a heapen, ha része egy ref típusnak. A lényeg, hogy az őt tároló konténernek közvetlen része, ami verem, ha lokális változó és heap, ha az egy ott lakó ref típus." Socinak pedig még egyszer hálásan köszönöm.

0 megjegyzés :

Megjegyzés küldése