Sorunun Geçmişi:
İşaretçiler, C++'nin ilk günlerinden beri dilin temel araçlarından biridir, bellek yönetimi ve dinamik yapılar için bir temel sağlar ve düşük seviyeli sistem kütüphaneleri ile etkileşimde bulunur. Referanslar daha sonra (C++ ile birlikte) sözdizimini basitleştirmek ve kodun güvenliğini artırmak amacıyla eklenmiştir.
Sorun:
Bellek ile ilgili hatalar, C++'de en yaygın sorunlardan biridir, özellikle işaretçilerin yanlış kullanımı (dangling pointers, bellek sızıntıları) durumunda. Bu durumda, bazen yeni başlayanlar hangi durumlarda referansın, hangi durumlarda işaretçinin kullanılacağını anlamaz ya da bunların tamamen birbirinin yerine geçebildiğini yanlış bir şekilde varsayar.
Çözüm:
İşaretçi (T*), bir nesnenin adresini saklayan bir değişkendir, nullptr olabilir, aritmetiği destekler, dinamik bellek tahsis ve serbest bırakmaya izin verir ve hangi nesneye işaret ettiğini değiştirebilir.
Referans (T&), başka bir mevcut nesnenin takma adıdır. Referanslar oluşturulurken başlatılmalıdır, "boş" olamaz (null referansı olamaz), aritmetiği desteklemez, ancak daha kullanışlı ve güvenlidir (örneğin, fonksiyonlara aktarırken).
Örnek Kod:
void increment_pointer(int* p) { if(p) ++(*p); } void increment_reference(int& r) { ++r; } int main() { int a = 5; increment_pointer(&a); increment_reference(a); }
Anahtar Özellikler:
nullptr olabilirBaşlatımından sonra referansı değiştirmek, başka bir nesneye işaret etmesini sağlamak mümkün mü?
Hayır. C++'de referans, sabit bir takma adıdır. Başlatımdan sonra referans her zaman aynı nesneye işaret eder, oysaki işaretçi yönlendirilebilir.
Kod örneği:
int a = 1; int b = 2; int& ref = a; // ref = b - b'nin değerini atar, ancak ref hala a'ya işaret eder
"Null" referansı veya nullptr'a referans oluşturmak mümkün mü?
Hayır, standart, mevcut olmayan nesnelere referanslara izin vermez. Bu, tanımsız davranışa yol açar.
Örnek:
int* p = nullptr; // int& r = *p; - UB
int* const ptr ile const int* ptr arasındaki fark nedir?
int* const ptr - değiştirilemeyen, ancak değeri değiştirilebilen bir işaretçidir. const int* ptr - sabit bir int'e işaret eden bir işaretçidir (işaret ettiği içeriği değiştiremezsiniz, ancak işaretçiyi yönlendirebilirsiniz).
Kod örneği:
int a = 1, b = 2; const int* ptr1 = &a; // *ptr1'i değiştiremeyiz, ptr1 = &b - bu mümkün int* const ptr2 = &a; // *ptr2'yi değiştirebiliriz, ptr2 = &b - bu mümkün değil
Genç bir geliştirici, parametreleri geçirmek için işaretçiler kullandı, onları nullptr açısından kontrol etmedi ve hatalar meydana geldiğinde çökme yaşadı.
Artılar:
Eksiler:
Deneyimli bir geliştirici, geçirmenin garanti olduğu durumlarda int& kullandı ve nullptr olabileceği durumlarda int* kullandı, işaretçiyi mutlaka null kontrolü yaparak kontrol etti.
Artılar:
Eksiler: