Menu
Coddy logo textTech

Sınıf Şablonları

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

Tıpkı fonksiyon şablonlarının türden bağımsız fonksiyonlar yazmanıza olanak tanıdığı gibi, sınıf şablonları da türden bağımsız sınıflar oluşturmanıza olanak tanır. std::vector gibi konteynerler bu şekilde çalışır; yapıyı bir kez tanımlarsınız ve derleyici kullandığınız her tür için özel sürümler oluşturur.

template <typename T>
class Box {
    T value;
public:
    Box(T v) : value(v) {}
    T getValue() const { return value; }
    void setValue(T v) { value = v; }
};

int main() {
    Box<int> intBox(42);
    Box<std::string> strBox("Hello");
    
    std::cout << intBox.getValue() << std::endl;  // 42
    std::cout << strBox.getValue() << std::endl;  // Hello
}

Fonksiyon şablonlarının aksine, sınıf şablonlarından nesneler oluştururken açılı ayraçlar kullanarak türü açıkça belirtmeniz gerekir. Derleyici daha sonra o belirli tür için tam bir sınıf tanımı oluşturur.

Sınıf şablonları birden fazla tür parametresine ve hatta tam sayılar gibi tür olmayan parametrelere sahip olabilir:

template <typename T, int Size>
class FixedArray {
    T data[Size];
public:
    T& operator[](int index) { return data[index]; }
    int size() const { return Size; }
};

FixedArray<double, 5> arr;  // 5 double'lık dizi
arr[0] = 3.14;

Üye işlevlerini sınıfın dışında tanımlarken şablon bildirimini tekrarlamanız gerekir:

template <typename T>
class Container {
    T* data;
public:
    Container();
    ~Container();
};

template <typename T>
Container<T>::Container() : data(nullptr) {}

template <typename T>
Container<T>::~Container() { delete data; }

Sınıf şablonları, C++'da jenerik programlamanın temelini oluşturur ve herhangi bir türle çalışan yeniden kullanılabilir veri yapıları yazmanıza olanak tanır.

challenge icon

Görev

Kolay

Her türden veriyi tutabilen esnek bir kapsayıcı oluşturmak için sınıf şablonlarını kullanarak genel bir depolama sistemi oluşturalım. Şablon sınıfınızı bir başlık dosyasında düzenleyecek ve ana programınızda farklı türlerle çok yönlülüğünü göstereceksiniz.

İki dosya oluşturacaksınız:

  • Storage.h: Bazı kullanışlı işlemlerle tek bir değer için basit bir kapsayıcı görevi gören Storage adlı bir sınıf şablonu tanımlayın:

    Storage şablonunuz şunlara sahip olmalıdır:

    • Depolanan değeri tutacak özel bir üye
    • Başlangıç değeri alan bir kurucu
    • Depolanan değeri döndüren bir getValue() metodu
    • Depolanan değeri güncelleyen bir setValue() metodu
    • Değer, T türünün varsayılan olarak oluşturulmuş değerine eşitse isEmpty(), aksi takdirde true döndüren bir false metodu

    Ayrıca, birbiriyle ilişkili iki değeri depolayan ve iki tür parametresine sahip Pair adlı bir sınıf şablonu oluşturun:

    • Birinci ve ikinci değerler için (potansiyel olarak farklı türlerde) özel üyeler
    • Her iki değeri başlatan bir kurucu
    • Her bir değeri almak için getFirst() ve getSecond() metotları
    • Şunu yazdıran bir display() metodu: (<first>, <second>)
  • main.cpp: Dört girdi okuyun (her biri ayrı bir satırda):
    1. Bir tamsayı değeri
    2. Yeni bir tamsayı değeri
    3. Bir string değeri
    4. Bir double değeri

    Şablonlarınızı şunları yaparak gösterin:

    1. İlk tamsayıyla bir Storage<int> oluşturup şunu yazdırma: Int storage: <value>
    2. setValue() kullanarak bunu ikinci tamsayıyla güncelleme, ardından şunu yazdırma: Updated: <value>
    3. String girdisiyle bir Storage<std::string> oluşturup şunu yazdırma: String storage: <value>
    4. String depolamasının boş olup olmadığını kontrol edip şunu yazdırma: Is empty: <true/false> (true veya false yazdırın)
    5. String ve double değerleriyle bir Pair<std::string, double> oluşturup ardından display() çağırma
    6. Her iki tamsayı girdisiyle bir Pair<int, int> oluşturup ardından display() çağırma

Örneğin, girdiler 42, 100, Hello ve 3.14 olduğunda:

Int storage: 42
Updated: 100
String storage: Hello
Is empty: false
(Hello, 3.14)
(42, 100)

Aynı Storage şablonunun tamsayılar ve string'lerle sorunsuz şekilde çalıştığına ve Pair'in farklı türleri bir araya getirebildiğine dikkat edin. Derleyici, kullandığınız her tür birleşimi için ayrı sınıf tanımları oluşturur. Tek tür şablonları için template <typename T> söz dizimini, birden çok tür parametresine sahip şablonlar için ise template <typename T, typename U> söz dizimini kullanmayı unutmayın.

Kendin dene

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

using namespace std;

int main() {
    // Girdileri oku
    int intValue1;
    int intValue2;
    string strValue;
    double doubleValue;
    
    cin >> intValue1;
    cin >> intValue2;
    cin >> strValue;
    cin >> doubleValue;
    
    // TODO: İlk tam sayı ile Storage<int> oluşturun ve yazdırın: Int storage: <value>
    
    // TODO: setValue() kullanarak ikinci tam sayı ile güncelleyin, yazdırın: Updated: <value>
    
    // TODO: Dize girişi ile Storage<std::string> oluşturun, yazdırın: String storage: <value>
    
    // TODO: Dize deposunun boş olup olmadığını kontrol edin, yazdırın: Is empty: true/false
    
    // TODO: Dize ve ondalıklı sayı ile Pair<std::string, double> oluşturun, display() fonksiyonunu çağırın
    
    // TODO: Her iki tam sayı ile Pair<int, int> oluşturun, display() fonksiyonunu çağı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

Kendi başına pratik yap: Online C++ derleyicisi