Yapı (Struct) ve Sınıf (Class) Arasındaki Farklar
Yapılar ve sınıflar ilk bakışta birbirleri ile büyük benzerlikler gösterir. Yapılar da sınıflar gibi tanımlanırlar. Özellikler, veriler, yapıcılar, metodlar içerebilir ve buna bağlı olarak da sınıflar gibi güçlü bir yapıdır diyebiliriz. Bu benzerliklere karşın sınıflar ile yapılar arasında önemli farklılıklar vardır.
Yapılar ile Sınıflar arasındaki en belirgin fark sınıfların referans türünde yapıların ise değer türünden olmasıdır. Bundan dolayı yapılar stack (yığın) alanı üzerinde, sınıflar ise heap (öbek) alanı üzerinde tutulurlar. Sınıflara referans aracılığıyla ulaşılırken yığınlara ise doğrudan ulaşabiliriz. Bu nedenle yapı kullanımı sınıf kullanımına göre daha az maliyetlidir ve erişim hızı yüksektir.
Yapılar genel olarak büyüklüğü belirli verileri saklamak için kullanılır. Çünkü stack (yığın) çok sınırlı bir veri alanıdır. Genelde büyüklüğü belirli verileri saklamak için kullanılırlar. Çok büyük miktarda veriyi bulundurmak için tasarlanmamıştır; kolayca stack overflow (yığın taşması) yaşanabilir. Çok büyük veriler için zaten öbek (heap) tasarlanmıştır.
Bir struct bildirimi varsayılan olarak kalıtımsal olduğundan sealed (inherit edilemez) tanımlanamaz. Çünkü varsayılan olarak kalıtımsallardır. Bu yüzden abstract, virtual, protected, internal olarak tanımlanamazlar. Ayrıca yapılar kendilerine belleğin stack (yığın) alanında yer edindikleri için yıkıcı (destructor) metodlar içermezler.
Aşağıda verdiğim örnekte iki sınıf ve iki yapı değişkeninin birbirleri ile olan ilişkisine bakalım:
class MyClass1 { public int x; public MyClass1(int x_Int) { x = x_Int; } } struct MyStruct1 { public int x; public MyStruct1(int x_Int) { x = x_Int; } } static void Main(string[] args) { MyClass1 r1, r2; MyStruct1 s1, s2; r1 = new MyClass1(10); r2 = new MyClass1(20); s1 = new MyStruct1(10); s2 = new MyStruct1(20); Console.WriteLine("r1.x:{0}, r2.x:{1}, s1.x:{2}, s2.x:{3}", r1.x, r2.x, s1.x, s2.x); //r1.x:10, r2.x:20, s1.x:10, s2.x:20 r1 = r2; s1 = s2; Console.WriteLine("o1=02, s1=s2"); Console.WriteLine("r1.x:{0}, r2.x:{1}, s1.x:{2}, s2.x:{3}", r1.x, r2.x, s1.x, s2.x); //o1=02, s1=s2 //r1.x:20, r2.x:20, s1.x:20, s2.x:20 r1.x = 100; s1.x = 200; Console.WriteLine("r1=r2, s1=s2"); Console.WriteLine("r1.x:{0}, r2.x:{1}, s1.x:{2}, s2.x:{3}", r1.x, r2.x, s1.x, s2.x); //r1=r2, s1=s2 //r1.x:100, r2.x:100, s1.x:200, s2.x:20 }
MyClass1 türünde r1 ve r2 isminde iki nesne ve MyStruct1 türünde s1 ve s2 isminde iki değişken tanımladık. Bu değişkenlere ilgili 10 ve 20 değerlerini atadıktan sonra r1 değişkenine r2’yi ve s1 değişkenine s2’yi atadık. Atamalar sonucunda s1’in s2’den bir kopya olduğunu fakat r1’in r2’den bir kopya oluşturmak yerine r2 ile aynı adresi işaret ettiğini gördük.
- 24063 okunma
Yorumlar
6 yorumC'den gelen Struct yapısı (Pascal'cılar ve Delphi'ciler record olarak bilirler) aslında çok basit bir yapı olmasına rağmen C# ile bu yapıya sınıflardakilere benzer işlevler ve yetenekler eklenmiş. Bu da genellikle OOP konusundaki bilgilerini tam oturtamamış yazılımcılar için kafa karıştırıcı olabiliyor. Yanlış bir soru olmasına rağmen sık sık şu soruyu duyuyoruz: "Struct mı kullanalım Class mı kullanalım?". Bu soruya cevap aramadan önce struct ve class yapılarını iyi anlamak lazım. Bu yazıda en temel farklılık olan referans ve değer veri tipleri olma özellikleri basit ve anlaşılır bir örnekle vurgulanmış. Teşekkürler.
Class ve struct arasındaki farkı güzel anlatmışsınız, teşekkürler. Yalnız bir şey sormak istiyorum." Atamalar sonucunda s1’in s2’den bir kopya olduğunu fakat r1’in r2’den bir kopya oluşturmak yerine r2 ile aynı adresi işaret ettiğini gördük." demişsiniz. Bunun sebebi nedir?
Bir sınıf değişkeni sınıfa ait nesnenin adresini barındırır. Dolayısıyla yapılan atamalarda sadece adresler aktarılır; adresteki nesnenin tamamı değil. Sınıf'ın Struct'tan farkı da budur.Örnektekiler gibi denemeler yaparsanız daha kolay anlaşılacaktır.
referans ve değer tipini anlamak için önce stack(yığın) ve heap(öbek ) anlamlarını bilmeniz gerekmekte. Şöyle stack bölgesi değer tipli verilerin tutulduğu heap bölgesi ise referans tipli verilerin tutulduğu bölgedir RAM ' de. Yani değer tipinden (struct türünden bir veri) geldiğinde RAM bunu stack bölgesinde tutacaktır, çünkü struct'lar değer tiplidirler ve dolayısıyla değer tipleri RAM' de yer tutarlar. Fakat class' lar referans tipli olduğundan RAM de yer tutmazlar kodlama yaparken class classAdi = new Class() diyerek ("new Class()") şeklinde yazdığın kod ile instance almış oluyorsun( RAM de o sınıf için yer ayırmış oluyorsun) ve dolayısıyla kullanacağın tüm veriler birbirini referans göstererek RAM de işlenecektir. Bu da sana RAM' den yer kazandıracaktır. Umarım anlatabilmişimdir.Saygılar,
Merhaba,konu ile alakalı olarak: struct tan oluşturduğum 2 nesnenin değerlerini aynı girip karşılaştırma yaptırdığım zaman sonuc eşit çıkıyor, Ancak class tan 2 aynı nesne oluşturup karşılaştırma yaptığım zaman bu eşitlik sağlanmıyor. Bunun sebebi ve hangi ilkeye bağlı olduğunu paylaşırsanız çok sevinirim.
s2 stack alanında bir referansa sahip s1'de s2'den aldığı verinin aynısını başka bir referans pointer alarak stack alanında tutmasından dolayı kopyası olarak nitelendirilir. r2, s2 gibi stack 'te bir referansa sahip r1'ise stack'te s1 gibi ayrı bir referans alarak bellekte fazla alan kaplamadan direk r2'ye ait referansı göstermektedir. Bu sayede performans artışı gözlenebilir. Küçük uygulamalarda pek sorun yaratmaz ancak kapsamlı bir uygulama yapıyorsanız bu yapı çok önemlidir.
Yeni yorum gönder