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.

İç içe sınıf, başka bir sınıfın içinde tanımlanan bir sınıftır. Bu teknik, ilişkili türleri bir arada gruplayarak kodu düzenlemeye yardımcı olur ve uygulama ayrıntılarını gizleyerek kapsüllemeyi güçlendirebilir.

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ıf Node, LinkedList ile sıkı bir şekilde bağlantılıdır - yalnızca bu bağlamda anlamlıdır. Onu iç içe yerleştirerek bu ilişkiyi belirtir ve genel ad alanını "Node" gibi genel bir adla kirletmekten kaçınırız.

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

public olarak bildirildiğinde, harici kod bunu kapsam operatörüyle kullanabilir:

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

Yönle ilgili önemli bir ayrıntı: iç içe geçmiş bir sınıf, onu çevreleyen sınıfın bir üyesidir ve diğer üyelerle aynı erişim haklarına sahiptir; bu nedenle herhangi bir friend bildirimi olmadan çevreleyen sınıfın private üyelerine erişebilir. Ancak tersi otomatik değildir: çevreleyen sınıfın, iç içe geçmiş sınıfın private üyelerine erişimi yoktur.

Bu nedenle Node, yukarıdaki örnekte friend class LinkedList; bildirir: friend bildirimi, kapsayan LinkedList'e Node'un özel üyelerine erişim izni verir; bu, otomatik olarak gerçekleşmeyen tek yöndür.

challenge icon

Görev

Kolay

Görevlerin bir proje içinde düzenlendiği basit bir görev yönetim sistemi oluşturalım. Bu, iç içe sınıflar için mükemmel bir senaryodur: Bir Task yalnızca bir Project bağlamında anlamlıdır; bu nedenle kodumuzu düzenli tutmak ve genel ad alanını gereksiz yere doldurmaktan kaçınmak için onu içine yerleştireceğiz.

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

  • Project.h: İç içe bir Task sınıfı içeren bir Project sınıfı tanımlayın.

    İç içe 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ı (string) ve tamamlanma durumu (bool) saklamalıdır. Adı alan ve görevi varsayılan olarak tamamlanmamış olarak ayarlayan bir kurucu verin. Görevi tamamlandı olarak işaretlemek için complete(), durumunu kontrol etmek için isComplete() ve adı almak için getName() yöntemlerini ekleyin.

    Project sınıfı, bir proje adı (string) ve Task işaretçilerinden oluşan bir koleksiyon saklamalıdır. Proje adını alan bir kurucu, yeni bir görev oluşturarak onu projeye ekleyen addTask(const std::string& taskName) yöntemi, ada göre bir görevi bulup tamamlayan completeTask(const std::string& taskName) yöntemi ve proje adını, ardından her görevin durumunu gösteren displayStatus() yöntemi sağlayın.

    Task, Project içinde iç içe olduğundan Project sınıfı görevlerle doğrudan çalışabilir. Dinamik olarak ayrılan görevleri yıkıcıda 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. Değişikliği göstermek için ilk görevi tamamlayın ve durumu tekrar görüntüleyin.

    displayStatus() için çıktı biçimi şö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 alıştırma, iç içe sınıfların ilişkili türleri düzenlemeye nasıl yardımcı olduğunu gösterir: Task sınıfı Project ile sıkı bir şekilde bağlantılıdır ve tek başına anlamlı olmazdı. Onu iç içe yerleştirerek bu ilişkiyi kod yapımızda açıkça belirtiriz.

Kendin dene

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

using namespace std;

int main() {
    // Girişi oku
    string projectName;
    string task1Name;
    string task2Name;
    
    getline(cin, projectName);
    getline(cin, task1Name);
    getline(cin, task2Name);
    
    // TODO: Verilen adla 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

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