Forum: Diğer Konular RSS
Pointer ve Referans
hsencan #1
Üye 2 haftadır · 9 mesaj · Konum: Afyonkarahisar
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Pointer ve Referans
Pointer ve referansın ne olduklarını biliyorum. Ama ikisi arasında ki farklar tam olarak nedir ?
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4644 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Arka planda hiçbir fark yok: ikisi de mikroişlemcinin sunduğu "şu adresteki değişkenden bahsetme" olanağını kullanıyorlar. Fark, programlama dili düzeyinde beliriyor.

C++: "Hiçbir şeye referans" olmuyor ama "hiçbir şeyi gösteren gösterge (pointer)" olabiliyor. Farklı söz dizimi kullanıyorlar: gösterge->üye ve referans.üye.

D'de bazı değişkenler referans olamıyor; örneğin, referans üye olamıyor ve referans yerel değişken olamıyor (gösterge kullanmak gerekiyor). D'de söz dizimi aynı gösterge.üye ve referans.üye. (D'de -> işleci yok.)

D'de sınıf değişkenleri nesne referansları:
    auto değişken = new Sınıf();
    değişken.üye = 42;    // İşlemci düzeyinde gösterge üzerinden erişim 
Aklıma gelenler bunlar.

Ali
kerdemdemir #3
Üye Eyl 2013 tarihinden beri · 168 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
Pointerlar çok güçlüler ama çok tehlikeliler. Bunu proje çok az büyüsün hemen görebiliyorsun. Bir de hafızadan dinamik olarak(malloc fonksiyonu veya new operatörü )alıp pointer atama yaptıktan sonra eğer pointer'ı silmeyi unutursan "memory leak" oluyor. Eğer bu "update loop" gibi kendini çok tekrar eden bir yerdeyse bir kaç dakka içinde bir bakmışssın hafıza kalmamış oluyor.

Pointerların dezavantaları sıralayacak olursam :

1 - null pointer üzerinden kontrol etmeden ulaşım yapılırsa programımız çöküyor.

A* a = nullptr;
a->foo();//-> Güm

2 - daha da kötüsü silinmiş(belleğe iade edilmiş) fakat null atanmamış bir pointer üzerinden bir fonksiyon çağırdığımızda "undefined behaviour" oluşuyor. En pisi de bu bence keşke patlasada nerde olduğunu anlasak diyor insan.
 
A* a = new A;
delete a;
a->foo();// Patlayamabilir ama ne yapacağı belli olmaz. İstediğin şeyi yapmıyacağı kesin. Böyle büyük projelerde (bu kadar basit formda değil tabi) çok olur bu didik didik arartırır adama kendini .


3 - Daha da pis bir pointer dezavantajı, pointer aritmetiği.
A* a = new A;
a += 2;// Evet bu yapılabilir çünkü pointerlar kontrolsüz güçlü
a->foo(); // İşte burda yine "undefined behaviour".
Yine tabi pratikde bu kadar basit bir hata kimse yapmıyor ama stackoverflow dediğimiz şey işte bunun türevlerinden oluyor. Sanıyorsam şu 12 yıllık meslek hayatımda aylarca aramışımdır bunlardan.

 
Şimdi ilk aklıma gelenler bunlar oldu. Böyle şeyler ile ömür tüketen biri olarak artık "new" operatörüne karşı bünyede alerji oluşuyor.

Referanslar eğer mümkünse çok daha güvenli oluyorlar. Eğer mümkünse her zaman pointerlar yerine referanslar kullanılmalı. Bunlar büyülü şeyler değil tabi arka planda pointer'lar ile gerçekleştiriliyorlar fakat işin pis taraflarını derleyice bırakmak çok iyi oluyor.

Referanslar pointerlar kadar esnek değiller. Kullanılmama sebepleri şunlar olabilir.

1 - Bir referansa başlangıç değer atamak zorundayız.

class A
{
    int *a; // derlenir
}

class A
{
    int& a; // tek başına derlenmez derlenmez
    A():a(5) {} // dememiz gerek
}

2 - Pointer 'lara "null" değeri atanıp kullanılabilir. Referanslarda null gibi ekstra bir opsiyon yoktur.

A* foo()
{
     bool disktenOkumaHatası  = DisktenOku();
     if ( disktenOkumaHatası )// işte böyle birşey oldu hayal edelim
         return nullptr; // Güzel aslında
      return new A();
}

A& foo()
{
     bool disktenOkumaHatası  = DisktenOku();
     if ( disktenOkumaHatası )// işte böyle birşey oldu hayal edelim
         // return nullptr; // Böyle bir geri dönüş değeri derlenmez.
         throw std::runtime_error("Kötü şeyler oldu");// Artık exception filan uğraşıcaz.
      return A();
}

Benim aklıma gelenler bunlar oldu.

Her ikisini kullanırkende oluşabilen dangling pointer/referance durumu olabilir. Dikkat etmek lazım.

Bunun dışında mümkün olduğunca referansları pointerlara tercih etmek lazım.

Erdemdem

Not: Yazmaya başladığımda Ali Abi'nin yazısı yoktu vay arkadaş en az yarım saat yazmışım demekki.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4644 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Söylediklerin doğru ama hemen hemen hepsi referanslar için de geçerli. Fark, kötü duruma düşmek göstergede kolay, referansta zor. D kullanarak gösteriyorum ama aynı durumlar C++'ta da var.

Referans olduğu için güvenip kullanan foo() işlevi yüzünden program çöküyor:
struct S {
    int * p;
    ref i() {
        return *p;
    }
}
 
// Bence hatasız yazılmış bir işlev:
void foo(ref int i) {
    i = 42;
}
 
void main() {
    auto s = S();
    foo(s.i);
}
Benzer örnekleri 2 ve 3 numaralı maddeler için de düşünebiliriz.

Evet, açıkça gösterge kullanmak çok daha riskli ama büyük programlarda referanslar da kendilerini kötü durumlarda bulabilirler. :)

D'nin en güzel taraflarından birisi, göstergelere hemen hemen hiç gerek olmuyor... demek istiyorum ama üye ve yerel değişken referans olamadığından oralarda gösterge gerekiyor.

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2018-02-24, 09:56:20 (UTC -08:00)