---
title: 'Sınıflar ve Erişim Denetimi'
source: 'https://academia.sh/tr/kurslar/cpp-temelleri/siniflar-ve-erisim-denetimi'
course: 'C++ Temelleri ve Nesne Tasarımı'
language: tr
updated: '2026-09-26T03:02:45+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Bir üye işlev çağrısında this işaretçisinin hangi nesneyi gösterdiğini ölçer'
    - "class ile struct'ın varsayılan erişim farkını ve public/private/protected'i uygular"
    - 'Erişim denetiminin nesne değil sınıf düzeyinde çalıştığını koşturarak gösterir'
---

# Sınıflar ve Erişim Denetimi

Bir üye işlevin hangi nesneyle çalıştığını ve erişim denetiminin nesne değil sınıf düzeyinde işlediğini ölçer.

Önceki ders bir serbest işlevin parametresine bakarak hangi nesneyle çalıştığını ölçtü:
`kaydir(Nokta n)` kendi kopyasıyla çalışıyordu, `tasi(Nokta* p)` çağıranın nesnesine
adresle ulaşıyordu. Bir **üye işlev**in de bir parametresi vardır, ama derleyici onu örtük
geçirir: çağrının yapıldığı nesnenin adresi. Bu örtük parametrenin adı `this`'tir ve bir üye
işlevin gövdesinde her zaman kullanılabilir — yazılmasa bile oradadır. Bu ders o örtük
parametreyi aynı çekirdekle ölçer: bir üye işlev çağrıldığında `this` hangi nesneyi
gösteriyor, ve bu bilgi erişim denetimiyle nasıl bir araya geliyor?

## Sınıf ve Erişim Denetimi

`class` ile `struct` C++'ta aynı şeydir; ikisi de üye değişken ve üye işlev taşıyabilen bir
tür tanımlar, ikisi de kalıtım alabilir, ikisi de yapıcı ve yıkıcı çalıştırır. Aralarındaki
tek fark varsayılan erişimdir. `struct` üyeleri varsayılan olarak `public`, `class` üyeleri
varsayılan olarak `private`'tır — başka hiçbir davranış farkı yoktur. Bu, C'den gelen bir
mirastır: C'de `struct` yalnız veri taşıyan bir kayıttı, işlev taşımazdı; C++ `struct`'a üye
işlev ekleme yeteneğini verirken geriye dönük uyumluluk için varsayılan erişimi `public`
bıraktı. Bir C++ kod tabanında `struct`'ın genellikle yalnız veri taşıyan, davranışı az
türler için, `class`'ın ise davranışı erişim denetimiyle koruyan türler için kullanılması bir
gelenektir — dilin kendisi bunu zorlamaz.

Bir sınıf üç erişim düzeyi bildirir:

- `public` — sınıfın dışından, herhangi bir kodun herhangi bir yerinden erişilebilir. Bir
  sınıfın dışarıya sunduğu **arayüz** buradadır.
- `private` — yalnız sınıfın kendi üye işlevlerinden (ve `friend` olarak bildirilmiş işlev ya
  da sınıflardan) erişilebilir. Bir sınıfın kendi iç durumunu tuttuğu veri üyeleri genellikle
  buradadır.
- `protected` — kendi üye işlevlerinden ve türeyen sınıflardan erişilebilir; `private`'tan
  farkı yalnız kalıtımda ortaya çıkar. Kalıtım M11/K04'ün ikinci konusuna kadar bu kursta
  kullanılmaz, bu yüzden `protected` burada yalnız adıyla anılır.

Bir erişim düzeyi bildirimi (`public:`, `private:` ya da `protected:`) bir sınıf gövdesinde
o noktadan sonraki tüm üyelere uygulanır, ta ki bir sonraki erişim düzeyi bildirimine kadar.
`Hesap` sınıfında `public:` altındaki üç üye işlev dışarıdan çağrılabilir, `private:` altındaki
`bakiye_` çağrılamaz — aynı sınıf gövdesinde birden çok `public:`/`private:` bloğu da
bulunabilir, derleyici hepsini birleştirir.

Bir sınıf **veri üyesi** (nesnenin her örneğinde ayrı bir kopyası olan değişken — `bakiye_`
her `Hesap` nesnesinde kendi değerini taşır) ve **üye işlev** (sınıfın tüm örnekleri arasında
paylaşılan, çağrıldığı örneğin veri üyelerine `this` üzerinden erişen kod — `yatir`'in
makine kodu bir kez üretilir, her `Hesap` nesnesi için ayrı ayrı değil) taşır. Bir üye işlev
`const` işaretliyse `this`'in kendisi `const`'tur: işlev veri üyelerini değiştiremez, yalnız
okuyabilir. `bakiye()` ve `esit_mi` bu yüzden `const`'tur — ikisi de `bakiye_`'yi okur ama
değiştirmez; `yatir` `const` değildir çünkü `bakiye_`'yi değiştirir. Bir `const` nesne
üzerinden yalnız `const` üye işlevler çağrılabilir; `const` olmayan bir üye işlevi `const`
bir nesne üzerinden çağırmak derleme hatasıdır, çünkü derleyici `this`'in işlev içinde
değiştirilmeyeceğini garanti edemez.

`friend` bildirimi bir işleve ya da sınıfa, üyesi olmadığı bir sınıfın `private` üyelerine
erişim tanır — erişim denetiminin tek istisnasıdır ve sınıfın kendi bildirimiyle açıkça
verilir, dışarıdan alınamaz. Bu kursta `friend` yalnız bir kez, `operator<<`'ın bir sınıfın
`private` veri üyesini okuyabilmesi için kullanılır (İşleç Aşırı Yükleme dersinde); burada
yalnız adıyla anılır.

Kapsülleme — bir sınıfın iç durumunu dışarıdan gizleyip yalnız işlevler üzerinden erişim
sunması — M08'de zaten işlendi; burada yeniden öğretilmez, yalnız C++'ın `public`/`private`
sözdizimiyle uygulanır. `Hesap` bu fikri uygular: `bakiye_`'ye dışarıdan
doğrudan yazılamaz, yalnız `yatir` üzerinden değiştirilebilir.

## Üye İşlevin `this`'i

`this`, bir üye işlevin gövdesinde örtük olarak tanımlı bir işaretçidir; tipi çağrıldığı
sınıfa göre belirlenir. `Hesap::yatir` içinde `this`'in tipi `Hesap* const`'tur — işaretçinin
kendisi değiştirilemez (başka bir `Hesap`'ı göstermeye başlayamaz), ama gösterdiği nesne
değiştirilebilir. `const` işaretli bir üye işlevde — `Hesap::bakiye() const` gibi — `this`'in
tipi `const Hesap* const`'tur: hem işaretçi hem gösterdiği nesne değiştirilemez, bu yüzden
`const` bir üye işlev veri üyelerine yalnız okuma erişimi kazanır. Kod bu işaretçiyi elle
yazmaz — `bakiye_ += miktar` derleyici tarafından `this->bakiye_ += miktar` olarak okunur —
ama aşağıdaki ölçüm `this`'in gerçekten çağrılan nesneyi gösterdiğini, başka bir nesneyi
değil, açıkça gösterir: `h.yatir(50)` çağrısından önce alınan `&h` adresiyle, işlev içinde
üstü kapalı kullanılan `this`'in eşdeğeri karşılaştırılır.

```cpp
// hesap.hpp — bakiyesi private olan bir hesap
#ifndef HESAP_HPP
#define HESAP_HPP

class Hesap {
public:
    void yatir(int miktar) { bakiye_ += miktar; }
    int bakiye() const { return bakiye_; }
    bool esit_mi(const Hesap& digeri) const { return bakiye_ == digeri.bakiye_; }

private:
    int bakiye_ = 0;
};

#endif
```

```cpp
// this-olcumu.cpp — uye islevin this'i cagrilan nesneyi mi gosteriyor
#include <cstdio>

#include "hesap.hpp"

int main() {
    Hesap h;
    Hesap* onceki = &h;

    h.yatir(50);
    std::printf("this cagrilan nesneyi gosteriyor mu %s\n", onceki == &h ? "evet" : "hayir");
    std::printf("bakiye %d\n", h.bakiye());
    return 0;
}
```

```text
this cagrilan nesneyi gosteriyor mu evet
bakiye 50
```

**SK3.** `h.yatir(50)` çağrısında derleyici `this`'e `&h`'yi geçirir; `yatir` içindeki
`bakiye_ += miktar` satırı `h.bakiye_`'yi değiştirir, başka hiçbir `Hesap`'ı değil. Bu ifade
**kendisi** sınıfındadır: `h`'nin kendisiyle çalışır.

## Erişim Denetimi Nesneyi Değil Sınıfı Sorar

`bakiye_` `private`'tır; `Hesap`'ın dışından `h.bakiye_` yazılamaz — `main` içinde böyle bir
satır denense derleyici reddeder, çünkü `main` `Hesap` sınıfının bir üyesi değildir. Ama
`Hesap`'ın kendi bir üye işlevi, **başka bir** `Hesap` nesnesinin `bakiye_`'sine doğrudan
erişebilir — erişim denetimi nesneyi değil, sınıfı sorar. `esit_mi` bunu gösterir:
`digeri.bakiye_` çağıranın kendi `bakiye_`'si değildir, ama aynı sınıftan olduğu için
derlenir. Bu, birçok dilde geçerli olmayan bir C++ kuralıdır — bazı dillerde erişim denetimi
nesne düzeyinde işler ve bir nesne yalnız kendi verisine dokunabilir; C++'ta sınır sınıfın
kendisidir, tek bir nesne değil.

```cpp
// esitlik-olcumu.cpp — bir uye islev baska bir nesnenin private uyesine erisiyor
#include <cstdio>

#include "hesap.hpp"

int main() {
    Hesap a;
    Hesap b;
    a.yatir(30);
    b.yatir(30);

    std::printf("a ile b esit mi %s\n", a.esit_mi(b) ? "evet" : "hayir");

    b.yatir(1);
    std::printf("a ile b esit mi %s\n", a.esit_mi(b) ? "evet" : "hayir");
    return 0;
}
```

```text
a ile b esit mi evet
a ile b esit mi hayir
```

**SK4.** `a.esit_mi(b)` içindeki `digeri.bakiye_` erişimi `b`'nin `private` üyesine
`a`'nın üye işlevinden yapılır; derleyici bunu yalnız `digeri`'nin tipine (`const Hesap&`)
bakarak kabul eder, `a` ile `b`'nin aynı nesne olup olmadığına bakmaz. Erişim kararı
**derleme zamanında**, sınıf bilgisine göre verilir.

Bu, birçok C++ öğrencisinin ilk şaşırdığı noktalardan biridir: `private`'ın "yalnız bu nesne
kendi verisine erişebilir" anlamına geldiği sanılır, ama kural budur — "yalnız bu **sınıfın**
üye işlevleri erişebilir." `esit_mi`'nin gövdesi derlenirken derleyici yalnız şunu bilir:
`digeri` bir `const Hesap&`'tır, ve o an derlenen işlev `Hesap` sınıfının bir üyesidir; bu iki
bilgi `digeri.bakiye_` erişimine izin vermek için yeterlidir. `a` ile `digeri`'nin (yani
`b`'nin) aynı çalışma zamanı nesnesi olup olmadığı derleme zamanında bilinmez ve erişim
kararına hiç katılmaz — nitekim ikinci çağrıda `a` ile `b` ayrı nesnelerdir ve erişim yine de
derlenir.

## private Neden Nesneyi Değil Sınıfı Korur

Bu kural rastgele değildir; sınıf yazarının **değişmezlerini** (invariant — bir nesnenin her
zaman doğru kalması gereken durumu, örneğin `bakiye_`'nin hiçbir zaman negatife düşmemesi)
korumasını mümkün kılar. Eğer `private` yalnız "başka nesnelerden değil, kendi nesnenden
erişilebilir" anlamına gelseydi, `esit_mi` gibi iki nesneyi karşılaştıran ya da bir nesneden
diğerine veri kopyalayan işlevler yazılamazdı — her üye işlev yalnız kendi `this`'ine
bakabilirdi. Sınıf düzeyinde erişim, bir sınıfın kendi üye işlevleri arasında güvenle veri
paylaşmasını sağlarken, sınıfın dışındaki koda aynı veriyi kapatır. Sınırı çizen nesne değil,
**sınıfın kaynak dosyasındaki bildirimdir.**

Bunun karşıtı, alanı dışarıya açık bırakılmış bir yapıdır: böyle bir kayıtta çağıran kod o
alanı herhangi bir denetimden geçirmeden değiştirebilir. `Hesap` aynı hatayı yapmaz —
`bakiye_`'ye dışarıdan yazma yolu yoktur, yalnız `yatir` üzerinden değiştirilebilir. `yatir`
bugün `bakiye_ += miktar` dışında bir şey yapmıyor, ama `private` sayesinde ileride negatif
bir `miktar`'ı reddetmek ya da bir üst sınırı denetlemek gibi bir kural eklense, bu kural
her çağıranı değiştirmeden yalnız `yatir`'in içine yazılabilir — çünkü `bakiye_`'ye giden
**tek yol** `yatir`'dir. Bu, `private`'ın sağladığı asıl mühendislik değeridir: sınıfın iç
temsilini değiştirme özgürlüğü, dışarıdaki koda dokunmadan.

## const Nesne Üzerinden Çağrı Seçimi

`bakiye()` ve `esit_mi` neden `const` işaretlidir, `yatir` neden değildir sorusunun bir
pratik sonucu vardır: bir `const Hesap&` parametre alan bir işlev, o parametre üzerinden
yalnız `const` üye işlevleri çağırabilir. `esit_mi`'nin imzası `bool esit_mi(const Hesap&
digeri) const`'tur; gövdesi içinde `digeri.bakiye_`'ye doğrudan erişir, ama `digeri.bakiye()`
çağırsaydı da derlenirdi — çünkü `bakiye()` `const`'tur ve `const` bir referans üzerinden
çağrılabilir. `digeri.yatir(10)` denenmiş olsaydı derlenmezdi: `yatir` `const` değildir, ve
`const` bir nesne (ya da `const` bir referansın gösterdiği nesne) üzerinden `const` olmayan
bir üye işlev çağrılamaz. Bu kural, bir işlevin imzasına `const` yazmasının yalnız belgeleyici
bir not olmadığını, derleyicinin gerçekten denetlediği bir sözleşme olduğunu gösterir:
`esit_mi`'nin `digeri`'yi değiştirmeyeceği, işlevin kendi imzasından derleme zamanında
doğrulanır.

Aynı kural `this` için de geçerlidir. `Hesap::esit_mi` `const` işaretli olduğu için kendi
`this`'i de `const Hesap* const`'tur; bu işlevin gövdesi içinde `bakiye_ += 1` gibi bir
değişiklik denense — kendi nesnesi üzerinde bile — derleyici reddeder. `const` bir üye
işlev, ne kendi nesnesini ne de `const` bir referansla aldığı başka bir nesneyi
değiştirebilir; değiştirebileceği tek şey yerel değişkenler ve `mutable` işaretli veri
üyeleridir (`mutable`, önbellekleme gibi nadir durumlar için ayrılmış bir işaretleyicidir ve
bu kursta kullanılmaz).

## Bildirim Sırası ve Erişim Düzeyi Blokları

`Hesap` sınıfında erişim düzeyi bildirimleri belli bir yerleşim sırası izler: önce `public:`
altında dışarıya sunulan üye işlevler, sonra `private:` altında veri üyesi. Bu sıra dilin bir
kuralı değildir — derleyici için `private:` üstte, `public:` altta olsaydı da aynı sonucu
verirdi — ama okunabilirlik için yaygın bir alışkanlıktır: bir sınıfı okuyan kişi önce onun
sunduğu arayüzü, sonra iç temsilini görür. Ters sıra (önce `private` veri, sonra `public`
işlevler) de geçerlidir ve bazı kod tabanlarında tercih edilir; bu ders `public`-önce
sırasını izler ve kursun geri kalanında tutarlı kalır.

Bir erişim düzeyi bildirimi yalnız bir kez kullanılmak zorunda değildir — aynı sınıf gövdesi
içinde `public:` ve `private:` birden fazla kez tekrarlanabilir, her biri kendinden sonraki
bloğu kapsar. `Hesap` bunu yapmaz; sınıf küçük olduğu için tek bir `public:` ve tek bir
`private:` yeterlidir. Daha büyük bir sınıfta, ilgili üyeleri bir arada tutmak için birden
çok blok kullanmak — örneğin yapıcılar için ayrı bir `public:`, sorgulayıcı işlevler için
ayrı bir `public:` — okunabilirliği artırabilir; bu bir stil tercihidir, derleyicinin
davranışını değiştirmez.

## Sınırlayıcı Ölçüm

Bu dersin ölçtüğü ifade **kendisi** sınıfındadır: `h.yatir(50)` `h`'nin kendisine yazar. Ama
erişim denetiminin sınırı da burada görülür: `private` bir üyeye "kimin eriştiği" nesne
düzeyinde değil sınıf düzeyinde sorulur. `esit_mi` içindeki `digeri.bakiye_` çağrısı bunu
kanıtlar — aynı sınıftan farklı bir nesnenin `private` üyesine, o nesnenin kendi işlevi
olmadan, yalnız aynı sınıfın bir başka üye işlevinden erişilebilir. `private`, nesneyi değil
sınıfın sınırını korur.

Bu sınırın bir sonucu daha vardır: `private` bir üyeye erişim, sınıfın **kendi** kaynak
kodundaki her üye işlevden mümkündür — bu üye işlevlerin sayısı sınıf büyüdükçe artabilir ve
her biri aynı değişmezi bozma riski taşır. `Hesap` üç üye işlevle küçüktür ve hepsi bu
derste görülebilir; büyük bir sınıfta `private` veriye erişen onlarca üye işlev olabilir, ve
bu derste ölçülen kural — erişimin nesneye değil sınıfa bağlı olması — o ölçekte de
değişmeden kalır. `private`, "kaç yerden erişilebilir" sorusuna nesne sayısıyla değil, sınıfın
üye işlev sayısıyla cevap verir.

Bu iki nokta — hangi ifadenin hangi nesneyle çalıştığı ve erişim denetiminin nesneyi değil
sınıfı sorduğu — birlikte okunduğunda bir sınıfın neden güvenilir bir sınır çizebildiğini
açıklar. `this` her çağrıda doğru nesneyi gösterir, bu yüzden bir üye işlev kendi nesnesini
başka bir nesneyle karıştırmaz; `private` her üye işleve aynı sınıftan gelen her nesneye
erişim tanır, bu yüzden sınıf kendi içinde veri paylaşımı gerektiren işlemleri (karşılaştırma,
kopyalama, birleştirme) yazabilir. Bu iki kural bir arada, bir sonraki dersin konusu olan
yapıcıya zemin hazırlar: bir yapıcı da bir üye işlevdir, kendi `this`'i vardır, ve `private`
veri üyelerine aynı serbestlikle erişir — ama onu farklı kılan, çağrıldığı nesnenin henüz
var olmayan bir nesne olmasıdır.

## Özet

- Bu dersin ölçtüğü ifade **kendisi** sınıfındadır: `h.yatir(50)` çağrısında `this`, `&h`'ye
  eşittir.
- `class` ile `struct`'ın tek farkı varsayılan erişimdir; `public`/`private`/`protected`
  üç erişim düzeyini bildirir.
- `const` işaretli bir üye işlevde `this` de `const`'tur; veri üyeleri değiştirilemez.
- Erişim denetimi **derleme zamanında** ve **sınıf düzeyinde** çalışır: bir üye işlev, aynı
  sınıftan başka bir nesnenin `private` üyesine erişebilir.
- Kapsülleme M08'de tanımlandı; burada yalnız `class`/`private` sözdizimiyle uygulandı.

## Sonraki Adım

Bu ders bir üye işlevin hangi nesneyle çalıştığını gösterdi; bir sonraki ders aynı soruyu
bir **yapıcı**ya sorar — `int`'ten örtük kurulan bir argümanın adsız, geçici bir
nesne olduğunu ve bu nesnenin tam olarak ne zaman yok olduğunu ölçer.
