ProgramlamaC++ Junior Geliştirici

Varsayılan üye başlatıcısının (default member initializer) mekanizmasını ve C++'ta sınıf üyelerinin başlatılma yöntemlerini açıklayın. Farklı yaklaşımlar performansı ve doğruluğu nasıl etkiler?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Varsayılan üye başlatıcı (default member initializer) — C++11'de tanımlanmış bir yapıdır ve sınıf üyesi değişkenlerinin başlatılması sırasında varsayılan değerler tanımlamaya olanak tanır. Bu özellik genellikle diğer veri başlatma yöntemleriyle karıştırılır.

Tarihçe

Eski C++ sürümleri, üyeleri doğrudan tanımlarken başlatmaya izin vermiyordu; değerler yalnızca kurucu içinde (gövde içinde veya başlatma listesinde) atanıyordu. Varsayılan üye başlatıcıların (C++11) getirilmesi, okunabilirliği artırmış ve belirsiz başlatma hataları riskini azaltmıştır.

Problem

Eğer alanlar açıkça başlatılmamışsa, "çöp" (belirsiz) değer içerirler. Kurucu içinde atama yapmak, başlatma listesinde kullanmaktan daha az etkilidir ve varsayılan üye başlatıcıları göz ardı etmek, sınıfların genişletilmesini ve yeni kurucuların oluşturulmasını zorlaştırır.

Çözüm

Basit değerler için varsayılan üye başlatıcıları kullanın, karmaşık durumlar için (özellikle bağımlı veya özel bir değere ihtiyaç varsa) kurucu başlatma listelerini tercih edin.

Kod örneği:

class Widget { int x = 42; // varsayılan üye başlatıcı std::string name = "default"; // varsayılan üye başlatıcı public: Widget() = default; // x=42, name="default" Widget(int xx) : x(xx), name("new") {}// x=xx, name="new" };

Önemli özellikler:

  • Varsayılan üye başlatıcısı, kurucu başlatma listesinde açık bir başlatma yoksa uygulanır.
  • Kurucu başlatma listelerinde başlatma, kurucu gövdesindeki atamadan daha etkilidir.
  • Varsayılan üye başlatıcıları, birçok kurucuya sahip sınıfların bakımını kolaylaştırır.

Zor Sorular.

Eğer bir üye kurucu gövdesinde başlatılmışsa, varsayılan üye başlatıcısı uygulanacak mı?

Cevap:

Hayır. Kurucu başlatma listesinde belirtilmediği takdirde, değişken öncelikle varsayılan değerle başlatılacak (varsayılan üye başlatıcı), ardından kurucu gövdesinde atama gerçekleşecektir, bu da daha az etkilidir.

Varsayılan üye başlatıcıları ile miras alındığında üye başlatma sırası nasıldır?

Cevap:

Öncelikle temel sınıf üyeleri, ardından türetilmiş sınıf üyeleri başlatılır; her bir üye için varsayılan üye başlatıcısı, öncelikle kurucu başlatma listesi ile uygulanır, eğer belirlenmişse, aksi takdirde varsayılan üye başlatıcı kullanılır; aksi takdirde başlangıç yapılmaz (POD için). "İki kez başlatma" olmaz.

Varsayılan üye başlatıcıları static üyelere uygulanabilir mi?

Cevap:

Hayır, static üyeler varsayılan üye başlatıcıları ile başlatılamaz. Onların sınıf dışında veya C++17'de inline static kullanarak başlatılması gerekir.

Örnek:

struct S { static int a = 5; // Hata! };

Yaygın Hatalar ve Antipatternler

  • Tek bir alan için varsayılan üye başlatıcısı ile gövde içinde atama yapmak.
  • Varsayılan üye başlatıcısının, başlatma listesi olup olmamasına bakılmaksızın uygulanacağını düşünmek.
  • Static üyeleri bu şekilde başlatmaya çalışmak.

Gerçek Hayat Örneği

Negatif Durum

Belirli kurucularda başlatma işlemi unutulan dinamik bir dizeye sahip bir sınıf. Daha sonra erişim sağlandığında — belirsiz davranış.

Artılar:

  • Hızla yazılır.

Eksiler:

  • Çöp değerlerinin riski; birçok kurucu için kötü bir genişletilebilirlik.

Pozitif Durum

Tüm alanların varsayılan üye başlatıcıları vardır. Ek kurucular gerektiğinde, gerekli üyeleri açıkça başlatmak için başlatma listesi kullanır.

Artılar:

  • Başlatılmamış üye yok.
  • Bakım daha kolay, yeni kurucular eklemek basit.