Soru Tarihçesi:
Başlangıç listesi, C++'da sınıf üyelerinin ana constructor gövdesi çalışmadan önce doğru ve optimize şekilde başlatılması için ortaya çıkmıştır. Bu, C ve C++ deneyimlerinden kaynaklanmıştır: sabit üyeleri ve referansları constructor gövdesinde başlatmak mümkün değildir, yalnızca başlangıç listesinde mümkündür.
Sorun:
Eğer bu tür üyeleri başlangıç listesi yerine constructor gövdesinde başlatmaya çalışırsanız, derleme hatası oluşur. Ayrıca, başlangıç listesinin göz ardı edilmesi, üye nesneler için çift başlatıcı çağrısı yapmayı tetikler ve bu da performansı etkiler, özellikle karmaşık başlatıcı constructor'larda.
Çözüm:
Sınıf üyelerini başlangıç listesi aracılığıyla deklarasyon ve başlatma yapmak en optimal yoldur — özellikle bu sabit (const) veya referans (&) olduğunda. Başlangıç listesi, constructor gövdesi çalışmadan ÖNCE devreye girer, üyeler henüz oluşturulmaktadır.
Kod örneği:
class Example { const int value; int& ref; public: Example(int v, int& r) : value(v), ref(r) { /* constructor gövdesi */ } };
Anahtar özellikler:
Sınıf üyelerinin ve başlangıç listesindeki başlatmaların sırası değiştirilirse ne olur?
Başlatma her zaman sınıf içindeki üyelerin beyan sırasına göre yapılır, başlangıç listesinde yazıldığı sıraya göre değil. Eğer bağımlı üyeler "yanlış sırada" başlatılmışsa, henüz başlatılmamış bir belleğe erişim söz konusu olabilir.
Kod örneği:
class Foo { int x; int y; Foo() : y(2), x(y) {} // x, henüz başlatılmamış y'nin değeriyle BİRİNCİ OLARAK başlatılacak }
Constructor gövdesinde const bir sınıf üyesini başlatmak mümkün mü?
Hayır. Bu, bir derleme hatasına yol açar. Sadece başlangıç listesi ile mümkündür.
Bir referans üyesini başlatmazsak ne olur?
Eğer bir referans üyesi başlatılmazsa, derleme hatası oluşur çünkü referans, oluşturulurken bir nesneye "bağlanmalı" ve daha sonra değiştirilemez.
Ayarları saklamak için bir sınıfta const std::string ve referans kullanılıyor, bu üyelerin başlatılma girişimi constructor gövdesinde yapılıyor, derleyici hata veriyor veya veriler başlatılmıyor.
Artılar: Yeni başlayan hata ile karşılaştı, atama ile oluşturma arasındaki farkı öğrendi.
Eksiler: Derleme hatası, sınıfın kullanılamaması, nesnelerin başlatılması sırasında beklenmedik hatalar olabilir.
Sabit ve referans doğru bir şekilde başlangıç listesi aracılığıyla başlatılıyor. Tüm karmaşık başlatma kodu listede yoğunlaştırılmış, bu da okunabilirliği arttırıyor ve hataları önlüyor.
Artılar: Sınıf üyelerinin güvenli ve doğru başlatılması, yüksek okunabilirlik, sızıntı veya UB olmaması.
Eksiler: Başlatmada karmaşık bir mantık oluşabilir, bir kısmı ek kod olmadan test edilmesi kolay olmayabilir.