Derinlemesine Erişim Belirleyiciler
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 35 / 104.
Üç erişim belirleyicisini anladığınıza göre, aynı sınıftan birden fazla nesneye sahip olduğunuzda nasıl davrandıklarını inceleyelim. Yaygın bir yanlış kanı, private ifadesinin "yalnızca bu nesne" anlamına geldiğidir - ancak aslında "yalnızca bu sınıf" anlamına gelir.
Aynı sınıfın nesneleri birbirlerinin özel (private) üyelerine erişebilir:
class Person {
std::string secret;
public:
Person(std::string s) : secret(s) {}
void readSecret(const Person& other) {
// Başka bir nesnenin özel üyesine erişiliyor - izin verilir!
std::cout << other.secret;
}
};Bu çalışır çünkü erişim kontrolü nesne düzeyinde değil, sınıf düzeyinde uygulanır. readSecret metodu Person sınıfının bir parçasıdır, bu nedenle herhangi bir Person nesnesinin özel (private) üyelerine erişebilir. Bu tasarım, kopya kurucular (copy constructors) ve karşılaştırma operatörleri gibi işlemlerin diğer nesnelerin iç durumuyla çalışmasına olanak tanır.
Bir sınıf içerisinde erişim belirleyicileri arasında birden fazla kez geçiş yapabilirsiniz:
class Mixed {
public:
void publicMethod1();
private:
int privateData;
public:
void publicMethod2(); // Tekrar public
private:
void privateHelper(); // Tekrar private
};Bu geçerli bir C++ kodu olsa da, okunabilirlik açısından üyeleri erişim düzeyine göre gruplandırmak genellikle daha iyidir. Çoğu stil kılavuzu, (sınıf arayüzünü oluşturdukları için) önce public üyelerin, ardından protected ve son olarak private üyelerin listelenmesini önerir.
Görev
KolayAynı sınıfa ait nesnelerin birbirlerinin özel (private) üyelerine nasıl erişebildiğini gösteren bir cüzdan karşılaştırma sistemi kuralım. Bu, C++ erişim kontrolü hakkında önemli bir bilgidir — erişim kontrolü nesne düzeyinde değil, sınıf düzeyinde uygulanır.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
Wallet.h: Özel finansal verileri saklayan ancak cüzdandan cüzdana karşılaştırmalara izin veren birWalletsınıfı tanımlayın. Sınıfınız şunlara sahip olmalıdır:- Özel (Private) üyeler:
ownerName(string) vebalance(double) - Sahip adını ve başlangıç bakiyesini alan bir yapıcı (constructor)
- Sahibin adını döndüren genel (public) bir getter
getOwnerName() - Bu cüzdanın bakiyesini başka bir cüzdanın özel bakiyesiyle karşılaştıran ve bu cüzdanda daha fazla para varsa
truedöndüren birhasMoreThan(const Wallet& other)metodu - Her iki cüzdanın özel bakiyelerinin toplamını döndüren bir
combinedBalance(const Wallet& other)metodu - Bu cüzdandan diğerine para taşıyan bir
transferTo(Wallet& other, double amount)metodu — her iki cüzdanın özel bakiyelerini doğrudan değiştirmelidir (yalnızca miktar pozitifse ve bu cüzdanın bakiyesini aşmıyorsa)
- Özel (Private) üyeler:
main.cpp: Nesneler arası özel üye erişimini gösterin. Girişten iki sahip adı ve iki bakiye okuyun (dört satır: name1, balance1, name2, balance2), ardından:- Giriş değerleriyle iki
Walletnesnesi oluşturun combinedBalance()kullanarak"Combined wealth: "Combined wealth: $yazdırın"lt;amount>" - Cüzdanları karşılaştırın ve hangi sahibin bakiyesi daha yüksekse
"<name> has more money"yazdırın (bunu belirlemek içinhasMoreThan()kullanın) transferTo()kullanarak birinci cüzdandan ikinciye100.0transfer edin"After transfer:"yazdırın"Combined wealth: "Combined wealth: $ifadesini tekrar yazdırın (değişmemiş olmalıdır)"lt;amount>" - Tekrar karşılaştırın ve
"<name> has more money"yazdırın (sonuç değişmiş olabilir)
- Giriş değerleriyle iki
Buradaki temel kavram, hasMoreThan() ve transferTo() gibi metodların başka bir Wallet nesnesinin özel balance üyesine doğrudan erişebilmesidir — getter'lara gerek yoktur. Bu, C++'ta erişim kontrolünün sınıf tabanlı olması nedeniyle çalışır: Wallet sınıfı içindeki herhangi bir kod, herhangi bir Wallet nesnesinin özel üyelerine erişebilir.
Tüm parasal değerleri <iomanip> kütüphanesinden std::fixed ve std::setprecision(2) kullanarak iki ondalık basamakla formatlayın. Bakiye girişlerini std::stod() kullanarak dönüştürün.
Kopya kağıdı
C++'da erişim kontrolü nesne düzeyinde değil, sınıf düzeyinde uygulanır. Bu, aynı sınıfın nesnelerinin birbirlerinin özel (private) üyelerine erişebileceği anlamına gelir:
class Person {
std::string secret;
public:
Person(std::string s) : secret(s) {}
void readSecret(const Person& other) {
// Başka bir nesnenin özel üyesine erişiliyor - izin verilir!
std::cout << other.secret;
}
};readSecret metodu, Person sınıfının bir parçası olduğu için herhangi bir Person nesnesinin özel secret üyesine erişebilir. Bu tasarım, kopyalama kurucuları ve karşılaştırma operatörleri gibi işlemleri mümkün kılar.
Bir sınıf içinde erişim belirleyicileri arasında birden fazla kez geçiş yapabilirsiniz:
class Mixed {
public:
void publicMethod1();
private:
int privateData;
public:
void publicMethod2(); // Tekrar public
private:
void privateHelper(); // Tekrar private
};Ancak, okunabilirlik açısından üyeleri erişim düzeyine göre gruplandırmak daha iyi bir uygulamadır. Çoğu stil kılavuzu, önce genel (public) üyelerin, ardından korumalı (protected) ve son olarak özel (private) üyelerin listelenmesini önerir.
Kendin dene
#include <iostream>
#include <string>
#include <iomanip>
#include "Wallet.h"
using namespace std;
int main() {
// Girdiyi oku: name1, balance1, name2, balance2
string name1, name2;
string balanceStr1, balanceStr2;
getline(cin, name1);
getline(cin, balanceStr1);
getline(cin, name2);
getline(cin, balanceStr2);
double balance1 = stod(balanceStr1);
double balance2 = stod(balanceStr2);
// Parasal değerler için çıktı biçimlendirmesini ayarla
cout << fixed << setprecision(2);
// TODO: Giriş değerleri ile iki Wallet nesnesi oluştur
// TODO: combinedBalance() kullanarak birleşik serveti yazdır
// Format: "Combined wealth: $<amount>"
// TODO: hasMoreThan() kullanarak cüzdanları karşılaştır ve kimin daha fazla parası olduğunu yazdır
// Format: "<name> has more money"
// TODO: transferTo() kullanarak birinci cüzdandan ikinciye 100.0 transfer et
// TODO: "After transfer:" yazdır
// TODO: Birleşik serveti tekrar yazdır
// TODO: Tekrar karşılaştır ve kimin daha fazla parası olduğunu yazdır
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 Konteyner