ProgramlamaC++ Geliştirici/Backend

C++'da delegasyon konstrüktörleri nedir, ne zaman ve neden kullanılır?

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

Cevap.

Konunun Tarihi

C++11 standartından önce, farklı parametrelere sahip birden fazla konstrüktör yazmak gerektiğinde, her birinde başlatma kodunun tekrarı yapılması gerekiyordu, çünkü sınıfın içindeki başka bir konstrüktörü çağırma imkanı yoktu.

Problem

Zaten mevcut olan başlatma mantığını diğer konstrüktörlerde kullanamamak, kodun tekrarlanmasına ve başlatma mantığındaki değişikliklerde hatalara yol açıyordu: bir konstrüktörü güncellediğinizde, diğerlerini unutmak kolaydı.

Çözüm

C++11 ile birlikte, bir sınıfın bir konstrüktörünün, o sınıfın başka bir konstrüktörünü başlatma listesindeki sözdizimiyle çağırmasına olanak tanıyan "delegasyon konstrüktörleri" mekanizması geldi.

Kod örneği:

class Widget { public: Widget() : Widget(0, "default") {} Widget(int n) : Widget(n, "user") {} Widget(int n, std::string name) : size(n), label(name) {} private: int size; std::string label; };

Artık tüm ortak mantık bir "ana" konstrüktörde toplanmıştır ve diğerleri çağrıyı delegasyon ediyor.

Anahtar özellikler:

  • Başlatma kodunun tekrarlanmasının önüne geçer
  • Güvenilirliği ve bakım kolaylığını artırır
  • Başlatma listesi içinde delegasyon, konstrüktörün gövdesinde değil

Kandırmaca Sorular.

Başka bir konstrüktörü, konstrüktör gövdesi içindeki bir fonksiyonu çağırarak delegasyonla çağırmak mümkün mü?

Hayır. Başka bir konstrüktörü çağırmak yalnızca başlatma listesi aracılığıyla mümkündür, konstrüktör gövdesi içinde değil. Eğer fonksiyonu konstrüktör gövdesinden çağırırsanız, nesne üyeleri zaten başlatılmış olacaktır.

Konstrüktörler arasında bir "döngü" delegasyonu oluşturulursa ne olur?

Döngüsel delegasyon (örneğin, A, B'ye; B ise A'ya delegasyon yapıyorsa) C++ derleme hatasına yol açar: Konstrüktörler arasında sonsuz özyineleme olamaz.

Bir türetilmiş sınıfın delegasyon konstrüktörü ile temel sınıfın konstrüktörünü çağırmak mümkün mü?

Hayır. Delegasyon konstrüktörleri yalnızca bir sınıfın içinde çalışır. Temel konstrüktörü çağırmak için ayrı bir sözdizimi kullanılır:

class Base { public: Base(int) {} }; class Derived : public Base { public: Derived() : Base(42) {} };

Tipik Hatalar ve Anti-Desenler

  • Aşırı delegasyon konstrüktörleri ile okunabilirliğin bozulması
  • Döngüsel delegasyon — derleme hatası
  • Bir delegasyon konstrüktörü aracılığıyla temel sınıfın konstrüktörüne çağrı yapma girişimleri

Gerçek Hayat Örneği

Olumsuz Durum

Üç konstrüktör, her biri açıkça alanları başlatır, mantık senkronize değildir — yalnızca bir konstrüktörde değişiklik adımına girin, diğer ikisi hatalıdır.

Artılar:

  • Yazması kolay

Eksiler:

  • Konstrüktörler arasında mantık farklılığı riski yüksektir.

Olumlu Durum

Bir ana konstrüktör, diğerleri ona delegasyon yapar, tüm başlatma mantığı merkezileştirilmiştir.

Artılar:

  • Kolay bakım, mantık farklılığı dışarıda bırakılmıştır.
  • Kod tekrarının en aza indirilmesi

Eksiler:

  • Başlatma listesi sözdizimine alışmak gerekir.