C++ Encapsulation ve Access Modifiers (public, protected, private)
C++’ta encapsulation ve access modifier kullanımını öğrenin. public, protected ve private ile veri gizleme ve güvenli sınıf tasarımı oluşturun.
Encapsulation (Kapsülleme), nesne yönelimli programlamanın (OOP) dört temel kavramından biridir. Bir sınıfın verilerini (özelliklerini) dış dünyadan gizleyip, bu verilere yalnızca tanımlanmış metotlar aracılığıyla erişilmesine izin verir. Bu yaklaşım veri bütünlüğünü korur ve sınıfın iç yapısını dış kullanımdan bağımsız hale getirir.
1) Encapsulation Nedir?
Encapsulation, “veri gizleme” prensibidir. Sınıfın içsel detayları (özellikler, yardımcı metotlar) dışarıya kapalıdır. Kullanıcı yalnızca sınıfın public arayüzü üzerinden etkileşime girer.
Bu sayede:
- Veri yanlış kullanımına karşı korunur.
- Sınıfın iç mantığı değiştirilebilir, dışarıdaki kod etkilenmez.
- Güvenlik, bakım kolaylığı ve test edilebilirlik artar.
2) Access Modifiers (Erişim Belirleyiciler)
C++’ta erişim belirleyiciler üç tanedir:
| Belirleyici | Erişim Düzeyi | Kullanım |
|---|---|---|
public |
Herkes erişebilir | Sınıf arayüzü (public API) |
protected |
Yalnızca sınıf ve alt sınıflar erişebilir | Kalıtımda kullanılacak ortak davranışlar |
private |
Yalnızca sınıf içinde erişilebilir | Veri alanları, yardımcı fonksiyonlar |
3) Book Sınıfı ile Kapsülleme Örneği
Aşağıda kapsüllemeyi temel alan bir Book sınıfı örneği yer alıyor.
#include <iostream>
#include <string>
using namespace std;
class Book {
private:
string title;
string author;
double price;
int pageCount;
public:
// Constructor
Book(string t, string a, double p, int pc)
: title(t), author(a), price(p), pageCount(pc) {}
// Getter ve Setter'lar
string GetTitle() const { return title; }
string GetAuthor() const { return author; }
double GetPrice() const { return price; }
void SetPrice(double p) {
if (p >= 0) price = p;
else cout << "Fiyat negatif olamaz!" << endl;
}
int GetPageCount() const { return pageCount; }
void Print() const {
cout << "Kitap: " << title
<< " | Yazar: " << author
<< " | Sayfa: " << pageCount
<< " | Fiyat: " << price << " TL" << endl;
}
};
int main() {
Book b("C++ Primer", "Lippman", 180.0, 950);
b.Print();
b.SetPrice(-50); // Geçersiz
b.SetPrice(210);
b.Print();
}
private alanlar doğrudan değiştirilemez. Değer değişikliği yalnızca SetPrice() gibi kontrollü bir
metot aracılığıyla yapılabilir.
4) protected Alanlar ve Kalıtım
Alt sınıflar, protected alanlara doğrudan erişebilir. Bu, alt sınıfın üst sınıfın verilerini genişletmesine olanak tanır.
class EBook : public Book {
protected:
string format; // Örn: PDF, EPUB
public:
EBook(string t, string a, double p, int pc, string f)
: Book(t, a, p, pc), format(f) {}
void PrintWithFormat() const {
cout << GetTitle() << " (" << format << ")" << endl;
}
};
Burada alt sınıf, kapsüllemeyi bozmadan ek özellik (format) kazandırdı.
5) friend Anahtar Sözcüğü
Normalde private üyeler sadece sınıf içinde erişilebilir.
Ancak bazen başka bir sınıfın veya fonksiyonun bu özel verilere erişmesi gerekebilir.
Bu durumda friend tanımlaması yapılabilir.
class Book {
private:
string title;
double price;
public:
Book(string t, double p) : title(t), price(p) {}
// friend fonksiyon tanımı
friend void ApplyDiscount(Book& b, double rate);
};
void ApplyDiscount(Book& b, double rate) {
b.price *= (1 - rate); // private alana erişim
}
int main() {
Book b("Design Patterns", 300);
ApplyDiscount(b, 0.1);
}
friend kullanımı dikkatli yapılmalıdır; çünkü kapsüllemeyi kırar.
Yalnızca çok gerekliyse (ör. operatör overload, debug araçları) tercih edilmelidir.
6) Getter ve Setter Tasarım İlkeleri
- Basit veri erişimleri için inline getter’lar kullanın (
constolmalı). - Setter içinde her zaman doğrulama (validation) yapın.
- Değer değişikliğine izin verilmeyen alanları readonly hale getirin (sadece getter).
- Gereksiz getter/setter tanımlamak yerine davranışı doğrudan metot olarak soyutlayın.
class Book {
private:
string title;
double price;
public:
Book(string t, double p) : title(t), price(p) {}
string GetTitle() const { return title; } // yalnızca okuma
void ApplyDiscount(double rate) { price *= (1 - rate); } // setter yerine davranış
};
7) const Anahtar Sözcüğü ile Veri Güvenliği
const metotlar sınıfın durumunu değiştirmez.
Bu, kapsüllemeyi destekler ve beklenmedik değişikliklerin önüne geçer.
class SafeBook {
private:
string title;
public:
SafeBook(string t) : title(t) {}
string GetTitle() const { return title; } // const metot
void SetTitle(string t) { title = t; }
};
const olmadan yazılan bir Get metodu, bu prensibi ihlal eder ve beklenmedik hatalara yol açabilir.
8) Immutable (Değiştirilemez) Nesne Deseni
Kapsülleme prensibine bağlı olarak bazı nesneler “değiştirilemez” (immutable) tasarlanır.
Tüm üyeleri const olur ve set metodu bulunmaz.
class ImmutableBook {
private:
const string title;
const string author;
const int pages;
public:
ImmutableBook(string t, string a, int p)
: title(t), author(a), pages(p) {}
string GetTitle() const { return title; }
string GetAuthor() const { return author; }
int GetPages() const { return pages; }
};
Bu yaklaşım özellikle çok iş parçacıklı ortamlarda veri bütünlüğünü garanti eder.
9) Kapsülleme ve Nesne Durum Yönetimi
Encapsulation yalnızca erişimi değil, nesnenin geçerli durumda kalmasını da sağlar. Sınıfın içsel durumu yalnızca tutarlı (valid) değerlerde olmalıdır.
class ValidatedBook {
private:
double price;
public:
void SetPrice(double p) {
if (p < 0) throw invalid_argument("Fiyat negatif olamaz.");
price = p;
}
};
Bu tür doğrulama mekanizmaları sınıfın “geçerli durumu”nu garanti eder ve dış kodun kötü veri göndermesini önler.
10) TL;DR
- Encapsulation, veriyi gizleyip davranışla erişim sağlamaktır.
private: yalnızca sınıf içi erişim.protected: sınıf ve alt sınıflar erişebilir.public: herkes erişebilir (sınıf arayüzü).friendile özel verilere dış erişim verilebilir (dikkatli kullanın).- Getter/setter’larda doğrulama ve
constkullanımı önemlidir. - Immutable nesneler veri güvenliği sağlar.
- Encapsulation, sürdürülebilir ve hatasız tasarımlar için temel ilkedir.
- Tüm örnekler Visual Studio 2022 ve GCC 11+ ortamında çalıştırılabilir.