İç İç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 iseYö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.
Görev
KolayGö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 birTasksınıfı içeren birProjectsınıfı tanımlayın.İç içe
Tasksınıfınız, dışarıdan erişilebilmesi içinProjectsı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çincomplete(), durumunu kontrol etmek içinisComplete()ve adı almak içingetName()yöntemlerini ekleyin.Projectsınıfı, bir proje adı (string) veTaskişaretçilerinden oluşan bir koleksiyon saklamalıdır. Proje adını alan bir kurucu, yeni bir görev oluşturarak onu projeye ekleyenaddTask(const std::string& taskName)yöntemi, ada göre bir görevi bulup tamamlayancompleteTask(const std::string& taskName)yöntemi ve proje adını, ardından her görevin durumunu gösterendisplayStatus()yöntemi sağlayın.Task,Projectiçinde iç içe olduğundanProjectsı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 birProjectoluş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;
}
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
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic KonteynerKendi başına pratik yap: Online C++ derleyicisi