Menu
Coddy logo textTech

İç İçe ve Dahili Sınıflar

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

Bir iç içe sınıf (nested class), başka bir sınıfın içinde tanımlanan bir sınıftır. Bu teknik, ilgili türleri bir araya getirerek kodu düzenlemeye yardımcı olur ve uygulama ayrıntılarını gizleyerek kapsüllemeyi (encapsulation) artırabilir.

class LinkedList {
public:
    class Node {    // İç içe geçmiş sınıf
        int data;
        Node* next;
    public:
        Node(int d) : data(d), next(nullptr) {}
        friend class LinkedList;
    };
    
private:
    Node* head;
    
public:
    LinkedList() : head(nullptr) {}
};

İç içe geçmiş Node sınıfı, LinkedList sınıfına sıkı bir şekilde bağlıdır - sadece bu bağlamda bir anlam ifade eder. Onu iç içe yerleştirerek bu ilişkiyi belirtiriz ve küresel ad alanını "Node" gibi genel bir isimle kirletmekten kaçınırız.

İç içe sınıflar, öğrendiğiniz erişim kurallarının aynısını takip eder. private bölümünde bildirilen bir iç içe sınıfa yalnızca dış sınıf içinden erişilebilir.

public olarak bildirildiğinde, harici kod onu kapsam operatörü ile kullanabilir:

LinkedList::Node node(42);    // Sadece Node public ise

Önemli bir detay: iç içe geçmiş sınıf (nested class), dış sınıfın özel (private) üyelerine otomatik olarak erişim sağlamaz. Bunlar, sadece aynı ad alanını (namespace) paylaşan ayrı sınıflardır.

Eğer iç içe geçmiş sınıfın erişime ihtiyacı varsa, yukarıdaki örnekte gösterildiği gibi onu bir friend olarak bildirmeniz gerekir.

challenge icon

Görev

Kolay

Görevlerin bir proje içinde organize edildiği basit bir görev yönetim sistemi kuralım. Bu, iç içe geçmiş sınıflar (nested classes) için mükemmel bir senaryodur — bir Task sadece bir Project bağlamında anlamlıdır, bu nedenle kodumuzu düzenli tutmak ve küresel ad alanını (global namespace) kirletmemek için onu içeriye yerleştireceğiz.

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

  • Project.h: İçinde iç içe geçmiş bir Task sınıfı barındıran bir Project sınıfı tanımlayın.

    İç içe geçmiş Task sınıfınız, dışarıdan erişilebilmesi için Project sınıfının public bölümünde bildirilmelidir. Bir görev adını (string) ve bir tamamlanma durumunu (bool) saklamalıdır. Ona adı alan ve görevi varsayılan olarak tamamlanmamış olarak ayarlayan bir yapıcı (constructor) verin. Görevi tamamlandı olarak işaretlemek için complete(), durumunu kontrol etmek için isComplete() ve adını almak için getName() metotlarını ekleyin.

    Project sınıfının kendisi bir proje adını (string) ve Task işaretçilerinden (pointers) oluşan bir koleksiyonu saklamalıdır. Proje adını alan bir yapıcı, yeni bir görev oluşturan ve projeye ekleyen bir addTask(const std::string& taskName) metodu, bir görevi adına göre bulup tamamlayan bir completeTask(const std::string& taskName) metodu ve proje adını ve ardından her görevin durumunu gösteren bir displayStatus() metodu sağlayın.

    Task, Project içinde iç içe geçtiği için, Project sınıfı görevlerle doğrudan çalışabilir. Yıkıcıda (destructor) dinamik olarak ayrılmış görevleri temizlemeyi unutmayın.

  • main.cpp: Girdiden bir proje adı ve iki görev adı (toplam üç satır) okuyarak her şeyi bir araya getirin. Verilen adla bir Project oluşturun, her iki görevi de ona ekleyin, ardından başlangıç durumunu görüntüleyin. İlk görevi tamamlayın ve değişikliği göstermek için durumu tekrar görüntüleyin.

    displayStatus() için çıktı formatı şöyle olmalıdır:

    Project: <project_name>
      - <task_name>: [incomplete]
      - <task_name>: [complete]

    Her görevin durumuna göre [complete] veya [incomplete] kullanın.

Bu zorluk, iç içe geçmiş sınıfların ilgili türleri düzenlemeye nasıl yardımcı olduğunu gösterir — Task sınıfı Project sınıfına sıkı sıkıya bağlıdır ve kendi başına bir anlam ifade etmez. Onu iç içe yerleştirerek, kod yapımızda bu ilişkiyi net bir şekilde belirtmiş oluruz.

Kopya kağıdı

Bir iç içe sınıf (nested class), başka bir sınıfın içinde tanımlanan bir sınıftır. İlgili türleri bir araya getirerek kodun düzenlenmesine yardımcı olur ve kapsüllemeyi (encapsulation) artırır.

class LinkedList {
public:
    class Node {    // İç içe sınıf
        int data;
        Node* next;
    public:
        Node(int d) : data(d), next(nullptr) {}
        friend class LinkedList;
    };
    
private:
    Node* head;
    
public:
    LinkedList() : head(nullptr) {}
};

İç içe sınıflar standart erişim kurallarına tabidir. Private bölümündeki bir iç içe sınıfa yalnızca dış sınıf içinden erişilebilir. Public olarak bildirildiğinde, harici kod kapsam operatörü (scope operator) ile onu kullanabilir:

LinkedList::Node node(42);    // Sadece Node public ise

İç içe sınıf, dış sınıfın özel (private) üyelerine otomatik olarak erişim hakkına sahip değildir. Erişim gerekiyorsa, onu bir friend olarak bildirin:

friend class LinkedList;

Kendin dene

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

using namespace std;

int main() {
    // Girdiyi oku
    string projectName;
    string task1Name;
    string task2Name;
    
    getline(cin, projectName);
    getline(cin, task1Name);
    getline(cin, task2Name);
    
    // TODO: Verilen isimle bir Project oluştur
    
    // TODO: Her iki görevi de projeye ekle
    
    // TODO: Başlangıç durumunu görüntüle
    
    // TODO: İlk görevi tamamla
    
    // TODO: Değişikliği göstermek için durumu tekrar görüntüle
    
    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