Konu Tarihi:
Klasik C++'da sınıf üyeleri yalnızca yapıcı inisyalizasyon listesinde başlatılabiliyordu. C++11 ile birlikte, sınıf içinde doğrudan bildirim sırasında varsayılan değerlerin belirtilmesi (member initializers) gibi bir olanak sunuldu, bu da kodun okunabilirliğini ve güvenliğini artırıyor.
Sorun:
Sınıf üyesine değer atamak için birkaç yol vardır: doğrudan bildirimde (in-class), yapıcı inisyalizasyon listesi üzerinden ve yapıcı gövdesinde. Farklı yollar performans ve semantiği etkiler; yanlış anlayış, gereksiz kopyalamalara ya da varsayılan yıkıcılara, sabitler ve referanslarla ilgili hatalara neden olur.
Çözüm:
class MyClass { int x = 42; };
class MyClass { const int y; MyClass(int val) : y(val) {} // aksi takdirde — derleme hatası };
class MyClass { std::string s; MyClass() { s = "hello"; } // Önce varsayılan, sonra atama };
Ana özellikler:
Üyelerin inisyalizasyon sırası: sınıfta ilan edildikleri sırayı mı, yoksa inisyalizasyon listesi sırasını mı takip eder?
İnisyalizasyon sırası her zaman sınıfta ilan edildikleri sıradır, inisyalizasyon listesi sırasıyla değil. Sıra ihlali, bağımlı üyeler için tehlikelidir.
class A { int x = 1; int y = 2; A() : y(10), x(20) {} }; // x, listede belirtilen sıraya rağmen y'den önce başlatılır
Eğer üye sabit, inisyalizasyon listesinde başlatılmadıysa, yapıcı gövdesinde başlatılabilir mi?
Hayır. Sabitler sadece inisyalizasyon listesinde başlatılır. Yapıcı gövdesinde atanması — derleme hatasıdır.
Eğer bir üye için doğrudan sınıfta in-class initializer kullanarak varsayılan değer verilirse ve bu değer yapıcı inisyalizasyon listesinde yeniden tanımlanırsa ne olur?
Yapıcı inisyalizasyon listesinde belirtilen değer kullanılacaktır. Varsayılan değer, liste hiçbir şey belirtmediğinde kullanılır.
class C { int x = 10; C() : x(20) {} // x 20 olacak };
Sınıf bir dosya ile çalışır. Dosya std::ofstream olarak bildirilmiş ve yapıcı gövdesinde başlatılmıştır. Tehlike: varsayılan yapıcı ile geçersiz bir std::ofstream oluşturulabilir, bu da dosyayla çalışma hatalarına yol açar.
Artılar:
Eksiler:
Dosya, inisyalizasyon listesinde başlatılır, böylece dosyanın geçersiz bir durumda kullanılmasını önler ve varsayılan verilere sahip üyeler in-class initializer kullanır.
Artılar:
Eksiler: