Smart
pointer C++ standart kütüphanesinde #include
<memory>
header dosyasında tanımlıdır ve amacı kaynak yönetiminin
otomatik gerçekleştirilmesini sağlamaktır. Pointer 'lar hafızada
belirli bir alanın adresini gösterir ve bu alanda verinin tutulması
için hafızada yer açma ve ilgili veri ile işlem bittiğinde bu
verinin silinmesi sorumluluğu programcıya aittir. Smart pointer
larda ise hafızanın boşaltılması işlemi otomatik olarak uygun
bir zamanda gerçekleştirilir.Uygun zaman biraz ucu açık bir
kavram tabi ki, isterseniz şimdi bir örnek üzerinden normal (raw)
pointer ile smart pointer farkını, hafızanın nasıl otomatik
silindiğine dair bir örnek üzerinden görelim;
Her iki
fonksiyonda da fonksiyon içerisinde bir pointer tanımlanıp,
pointer ın işaret ettiği alana değer ataması yapılıyor. Daha
sonra ise fonksiyon içerisindeki yerel değişkenlerin adresi global
değişkenlerin adresine atanıyor. Ekran çıktısında göreceğiniz
gibi raw pointer ın atandığı global *y değeri ile *x
aynı değere sahip. Çünkü x ve y
değişkenleri aynı hafıza adresini gösteriyor. Fakat main
içerisindeki smart pointer global *sy nin değeri ise ekrana
boş olarak yazdırılıyor. sy.reset(sx.get()); kod
parçacığı ile sx pointer ı resetlendi, yani artık saklanan nesnenin yeni sahibi sy oldu!.
unique_ptr kullandığımız için sy = sx ataması
yapamıyoruz yani iki ayrı pointer ın aynı hafıza adresini
göstermesini sağlayamıyoruz! UseSmartPointer içerisindeki
(smart x :)) sx isimli akıllı pointer ımız tanımlandığı
fonksiyonun kapsamının dışına çıkınca sx in işaret
ettiği yerdeki değer otomatik olarak siliniyor. (Not: sy
nin değerini boş yazacak dedik ama aslında sy pointer ı da
silindi ve ona erişemiyoruz, çünkü sx ile aynıydı :) yani
kod aslında hata verecek ama amacımız zaten otomatik silinmeyi
göstermek idi) İlk paragrafta bahsettiğimiz uygun bir zaman
kavramına geri dönecek olursak; uygun zaman bu örnek için kapsama
alanının dışına çıkılması anlamına geliyor. Özetle; smart pointer da tutulan veriler, kapsama alanının dışına
çıkılınca otomatik olarak siliniyor!!!
Yukarıda
verdiğimiz örnekte UseRawPointer
fonksiyonundaki x pointer ını silmedik bu nedenle hafızada yer
kaplamaya devam ediyor olacak. Ayrıca bu örnekte unique_ptr
kullandık, unique_ptr
şu anlama geliyor: aynı kaynağı işaret eden en fazla
bir pointer olabilir. Şimdi
vereceğim örnekte ise shared_ptr
kullanacağız. shared_ptr
ile birden fazla pointer aynı kaynağa işaret edebilir..
Ekran
çıktısına baktığımızda raw pointer ile aynı davrandı. sx
pointer ı kapsama alanı dışında kaldığı için otomatik olarak
silindi, Fakat sy hala verinin saklandığı yeri gösteriyor.
Buradaki avantaj akıllı pointer sx i silmek ile uğraşmadık, boş
yere de yer kaplamamış oldu.
shared_ptr
kullanarak
ilgili kaynağı kaç farklı pointer ın işaret ettiğini de
öğrenebiliriz (reference
counting).
Örneğin aşağıdaki örnekte 2 pointer aynı değeri işaret
ediyor, ve bu pointer lardan birisini silince use_count
değeri bir azalıyor.
Bir
başka akıllı pointer tipi ise weak_ptr
'dir.
weak_ptr
shared_ptr
ile yönetilen bir nesneye referans olan bir akıllı pointer dır.
C++
ta bir pointer ın sahipliği kavramı, pointer ın sakladığı
veriyi kimin silme sorumluluğu taşıdığı ile alakalıdır.
weak_ptr
işaret edilen nesne üzerinde geçici bir sahiplik sağlar, yani
işaret ettiği hafızadaki nesne aynı(değişmeden) kaldığı
müddetçe ilgili hafıza adresini saklar. Fakat weak_ptr
nin işaret ettiği yerdeki değer değişirse
weak_ptr
(adı
üstünde zayıf)
nin bağlantısı da kopar. Bu sebeple de weak_ptr
deki verinin geçerliliği expired()
ya da lock()
metodları
ile kontrol edilmelidir. Bu senaryoya ilişkin örnek ve ekran
çıktısı aşağıdaki gibidir.
guzel
YanıtlaSil