[Çözüldü] Sınıf implementasyonu hangisi daha doğru

Başlatan desert_eagle, 12 Aralık 2014 - 16:45:31

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

desert_eagle

Merhaba,

A *obj = new A(); ile A obj; tanımlamasındaki temel fark tam olarak nedir? Tamam ilkinde pointer olarak tanımlanıyor bu yüzden fonksiyonlara ulaşmak için "->" operatörü kullanılıyor diğerinde direk ulaştığımız için "." kullanılıyor
ikisinde de construct fonksiyonu bu tanımlamalar olduğu an çalışıyor. Yani sınıf implemente edilmiş oluyor sanırım. Yoksa sadece bir kullanım alışkanlığı ile ilgili midir? Hafıza açısından bir fark oluşturur mu? Tam nasıl araştıracağımı da bilemedim internette bu durumu  :o

Teşekkürler

Amenofis

Cevap yazmıştım ama bağlantı problemi yüzünden kayboldu.>:(

Stack vs heap diye arat en iyisi.

desert_eagle

Anladığımı yazayım öncelikle
A obj; stack ta
A *obj = new A(); heap te saklanır.

Böyle olduğunu varsayarsak aradaki fark stack ta saklanan değişkene daha hızlı erişilir.
Hızlı işlem yapmak gibi bir hedefimiz olduğu kısım için ilk şekilde tanımlamak doğru olacaktır. Ancak stack alanı daha dar olduğu için her sınıfı bu şekilde kullanmamalıyız.

Yanlışı yada eksiğimi düzeltirseniz sevinirim.

Amenofis

Nesneyi stack üzerinde oluşturmak daha hızlı olsa da erişim hızı aynıdır fakat konu o değil.
Stackteki nesneler geçicidir, kapsam dışına çıkınca yok olurlar.
void foo()
{
    A obj; // constructor çağrılır
    ...
} // fonksiyon sonlanmadan önce destructor çağrılır, nesnenin ömrü biter

Heapteki nesneler ise özellikle yok etmediğimiz sürece kalıcıdır.
void foo()
{
    A *obj = new A; // constructor çağrılır
    ...
} // nesne hala bellekte
İkinci durumda nesne yok edilmediği için yerinde durur ama onu gösteren işaretçi yok olduğu için artık nesneye erişim mümkün olmaz. Bu durumda bellek sızıntısı (memory leak) var demektir.

Kısaca stack, heap olayları bellek yönetimi ile ilgili ve oldukça karmaşık konular.

desert_eagle

Çok teşekkür ederim. Önemli bir konu daha bilinçli kod yazabilmek için güzel bir bilgi.
Ben biraz daha aklıma takılanları sormak istiyorum.
Eğer hiç sonlandırmak istemezsek fonsiyonun dışında global tanımlama yaptığımızda  A obj; yada  A *obj = new A(); gibi kullanmak lazım sanırım.
Bu durumda oluşturulan sınıf stack ve heap ın dışında global'lerin tutulduğu ayrı bir mantıksal alanda tutuluyor diyebiliriz.

Şöyle * bir şey denedim. Önce global olarak tanımladım( A *obj = new A();) . sınıfın içindeki foo() fonksiyonunu kullandım sıkıntı olmadı daha sonra oluşturulan nesneyi "delete obj;" kullanarak sildim.
Tekrar kullanmaya çalışınca doğal olarak runtime error aldım.
Sorum şu olacak; normalde global değerler hafızadan bu şekilde silinmesine derleyici izin vermesi doğru mu değeri değişse bile o bölge derleme sırasında ayrılmış olmuyor mu? Hadi sildi diyelim ama bu bölge global değişkenlerin kısmı derleme sırasında ayarlandığı için atıl olarak kalmış mı oluyor?

Amenofis

#5
Yanlış anlaşılmalara yol açmamak için "nesne" nedir onu açalım önce. C++ ta nesne "adı koyulan" bellek bölgesi dir. Yani char, int, double, struct, union, class, void* vs. bütün türdeki değişkenler ve bunları gösteren işaretçilerin hepsi nesnedir. Ve derleme zamanında yeri tayin edilen hiçbir nesne çalışma zamanında yok edilemez.

Global ve static nesneleri derleyici mantıksal olarak ayrı gruplasa da hepsi heap bölgesine ait.

A obj; ifadesinde tek nesne var o da obj.
A *obj = new A; ifadesinde 2 nesne var. Birisi new ile çalışma zamanında yeri belirlenen A türünden bir nesne. Diğeri ise bu nesneyi işaret eden, derleme anında yeri belirlenen obj işaretçisi.

A *obj = new A; ifadesi global olsa bile "new" ile tanımlanan bütün nesnelerin yeri çalışma zamanında belirlenir. Derleyici globaller için bellek tahsisini main e girmeden önce yapar. delete obj; dediğin zaman A nesnesi silinir ama onu gösteren işaretçi kalır. Sonradan bu işaretçiyi başka bir nesneyi göstermek amacıyla kullanabilirsin ama onu silemezsin.