Menu
Coddy logo textTech

Temsilci Yapıcılar

Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 23 / 104.

Ortak başlatma mantığını paylaşan birden fazla kurucunuz olduğunda, kod tekrarını önlemek için devreden kurucular (delegating constructors) kullanabilirsiniz. Bir devreden kurucu, kendi başlatıcı listesinde aynı sınıfın başka bir kurucusunu çağırır.

class Player {
    std::string name;
    int health;
    int level;
public:
    // Birincil kurucu - asıl işi yapar
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Birincil kurucuya delege eder
    Player(std::string n) : Player(n, 100, 1) {}
    
    // Varsayılan kurucu da delege eder
    Player() : Player("Unknown") {}
};

Delegasyon, sınıf adının ardından argümanların kullanıldığı başlatıcı listesinde gerçekleşir. Player() çağrıldığında, Player(std::string) yapıcısına delege eder, o da daha sonra üç parametreli yapıcıya delege eder. Zincir, hedef yapıcıdan orijinal yapıcıya doğru yürütülür.

Önemli bir kural vardır: delege eden bir kurucu (delegating constructor), başlatıcı listesinde (initializer list) başka üyelere sahip olamaz. Delege etme işlemi listedeki tek öğe olmalıdır:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // Hata! Delegasyon ile üye ilklendirme bir arada kullanılamaz
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Doğru - sadece delegasyon
    Item(int i) : Item(i, 0) {}
};

Temsilci kurucular (delegating constructors), başlatma mantığını tek bir yerde merkezileştirmeye yardımcı olarak kodunuzun bakımını kolaylaştırır ve yinelenen kodlardan kaynaklanan hatalara karşı daha az eğilimli hale getirir.

challenge icon

Görev

Kolay

Kurucu delegasyonunun (delegating constructors), kurucu çağrılarını birbirine zincirleyerek kod tekrarını nasıl ortadan kaldırabileceğini gösteren bir bağlantı ayarları sistemi oluşturalım.

Kodunuzu düzenlemek için iki dosya oluşturacaksınız:

  • Connection.h: Çeşitli yapılandırma seçeneklerine sahip bir ağ bağlantısını temsil eden bir Connection sınıfı tanımlayın. Sınıfınız şunlara sahip olmalıdır:
    • Özel (private) üyeler: host (string), port (int), timeout (saniye cinsinden int) ve secure (bool)
    • Dört parametrenin tamamını alan ve bir başlatıcı listesi (initializer list) kullanarak tüm üyeleri başlatan bir birincil kurucu (primary constructor). Bu kurucu "Connection configured: <host>:<port>" metnini yazdırmalıdır.
    • Yalnızca host ve port alan, timeout değerini varsayılan olarak 30 ve secure değerini varsayılan olarak false yaparak birincil kurucuya delege eden bir kurucu.
    • Yalnızca host alan ve port değerini varsayılan olarak 80 yaparak iki parametreli kurucuya delege eden bir kurucu.
    • host değerini varsayılan olarak "localhost" yaparak tek parametreli kurucuya delege eden bir varsayılan kurucu (default constructor).
    • Şu formatta bir string döndüren bir getInfo() metodu: "<host>:<port> (timeout: <timeout>s, secure: <yes/no>)"
  • main.cpp: Farklı kurucuları kullanarak bağlantılar oluşturarak delegasyon zincirini gösterin. Girişten bir host adı ve bir port numarası okuyun (her biri ayrı bir satırda), ardından:
    • Varsayılan kurucuyu kullanarak bir Connection oluşturun.
    • Yalnızca girişten alınan host'u kullanarak bir Connection oluşturun.
    • Girişten alınan hem host hem de port'u kullanarak bir Connection oluşturun.
    • Giriş host'u, giriş port'u, 60 timeout değeri ve true olarak ayarlanmış secure değeri ile bir Connection oluşturun.
    • Her bağlantı için getInfo() sonucunu her satıra bir tane gelecek şekilde yazdırın.

Delegasyon zinciri şu şekilde ilerler: varsayılan kurucu tek parametreli kurucuyu çağırır, o iki parametreli kurucuyu çağırır, o da birincil dört parametreli kurucuyu çağırır. Bu, "Connection configured" mesajının oluşturulan her nesne için her zaman birincil kurucudan bir kez yazdırılacağı anlamına gelir.

getInfo() içindeki secure durumu için, secure true ise "yes", aksi takdirde "no" yazdırın.

Başlık dosyanızı main.cpp içine #include "Connection.h" kullanarak dahil edin.

Kopya kağıdı

Bir delegating constructor (devreden kurucu), kod tekrarını önlemek için başlatıcı listesinde (initializer list) aynı sınıfın başka bir kurucusunu çağırır:

class Player {
    std::string name;
    int health;
    int level;
public:
    // Birincil kurucu
    Player(std::string n, int h, int lvl) 
        : name(n), health(h), level(lvl) {}
    
    // Birincil kurucuya devreder
    Player(std::string n) : Player(n, 100, 1) {}
    
    // Varsayılan kurucu da devreder
    Player() : Player("Unknown") {}
};

Devretme işlemi, başlatıcı listesinde sınıf adının ardından argümanların kullanılmasıyla gerçekleşir. Kurucular, birinin diğerine devrettiği bir devretme zinciri oluşturabilir.

Önemli kural: Bir delegating constructor, başlatıcı listesinde başka üyelere sahip olamaz. Devretme işlemi listedeki tek öğe olmalıdır:

class Item {
    int id;
    int value;
public:
    Item(int i, int v) : id(i), value(v) {}
    
    // Hata! Devretme ile üye başlatma karıştırılamaz
    // Item(int i) : Item(i, 0), id(i) {}
    
    // Doğru - sadece devretme
    Item(int i) : Item(i, 0) {}
};

Kendin dene

#include <iostream>
#include <string>
#include "Connection.h"

using namespace std;

int main() {
    // Girdiyi oku
    string host;
    int port;
    cin >> host;
    cin >> port;

    // TODO: Varsayılan yapıcıyı (default constructor) kullanarak bir Connection oluşturun

    // TODO: Sadece girdiden alınan host bilgisini kullanarak bir Connection oluşturun

    // TODO: Girdiden alınan hem host hem de port bilgilerini kullanarak bir Connection oluşturun

    // TODO: Girdi host, girdi port, timeout=60 ve secure=true parametreleriyle bir Connection oluşturun

    // TODO: Her bağlantı için getInfo() sonucunu her satıra bir tane gelecek şekilde yazdırın

    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler