Erişim Belirleyicilerine Derinlemesine Bakış
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 35 / 104.
Artık üç erişim belirleyiciyi anladığına göre, aynı sınıftan birden fazla nesne olduğunda nasıl davrandıklarını inceleyelim. Yaygın bir yanlış kanı, private'ın "yalnızca bu nesne" anlamına geldiğidir; ancak aslında "yalnızca bu sınıf" anlamına gelir.
Aynı sınıftaki nesneler birbirlerinin 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 private üyesine erişmek - buna izin verilir!
std::cout << other.secret;
}
};Bu, erişim denetimi nesne düzeyinde değil, sınıf düzeyinde uygulandığı için çalışır. readSecret yöntemi Person sınıfının bir parçasıdır; bu nedenle herhangi bir Person nesnesinin özel üyelerine erişebilir. Bu tasarım, kopya oluşturucular ve karşılaştırma işleçleri gibi işlemlerin diğer nesnelerin iç durumuyla çalışmasını sağlar.
Bir sınıf içinde erişim belirleyicileri arasında birden çok kez geçiş yapabilirsiniz:
class Mixed {
public:
void publicMethod1();
private:
int privateData;
public:
void publicMethod2(); // Yeniden public
private:
void privateHelper(); // Yeniden private
};Bu geçerli bir C++ olsa da okunabilirlik için üyeleri erişim düzeylerine göre gruplamak genellikle daha iyidir. Çoğu stil kılavuzu, önce public üyelerin (sınıf arayüzünü oluşturdukları için), ardından protected üyelerin ve son olarak private üyelerin listelenmesini önerir.
Görev
KolayNesnelerin aynı sınıftan diğer nesnelerin private üyelerine nasıl erişebildiğini gösteren bir cüzdan karşılaştırma sistemi oluşturalım. Bu, C++ erişim denetimiyle ilgili temel bir içgörüdür: denetim nesne düzeyinde değil, sınıf düzeyinde uygulanır.
Kodunu düzenlemek için iki dosya oluşturacaksın:
Wallet.h: Private finansal verileri saklayan ancak cüzdanların birbirleriyle karşılaştırılmasına izin veren birWalletsınıfı tanımla. Sınıfında şunlar bulunmalı:- Private üyeler:
ownerName(string) vebalance(double) - Sahibin adını ve başlangıç bakiyesini alan bir kurucu
- Sahibin adını döndüren bir public getter olan
getOwnerName() - Bu cüzdanın bakiyesini başka bir cüzdanın private 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 private bakiyelerinin toplamını döndüren bir
combinedBalance(const Wallet& other)metodu - Bu cüzdandan başka bir cüzdana para aktaran bir
transferTo(Wallet& other, double amount)metodu. Bu metot, her iki cüzdanın private bakiyelerini doğrudan değiştirmeli (yalnızca miktar pozitifse ve bu cüzdanın bakiyesini aşmıyorsa)
- Private üyeler:
main.cpp: Nesneler arası private üye erişimini göster. Girdiden iki sahibin adını ve iki bakiyeyi oku (dört satır: name1, balance1, name2, balance2), ardından:- Girilen değerlerle iki
Walletnesnesi oluştur combinedBalance()kullanarak"Combined wealth: $<amount>"yazdır- Cüzdanları karşılaştır ve bakiyesi daha yüksek olan sahibin adını
"<name> has more money"biçiminde yazdır (bunu belirlemek içinhasMoreThan()kullan) transferTo()kullanarak ilk cüzdandan ikinci cüzdana100.0aktar"After transfer:"yazdır"Combined wealth: $<amount>"ifadesini tekrar yazdır (değer değişmemeli)- Tekrar karşılaştır ve
"<name> has more money"yazdır (sonuç değişmiş olabilir)
- Girilen değerlerle iki
Buradaki temel kavram, hasMoreThan() ve transferTo() gibi metotların başka bir Wallet nesnesinin private balance üyesine doğrudan erişebilmesidir: getter gerekmez. Bu, C++'ta erişim denetiminin sınıf tabanlı olmasından kaynaklanır: Wallet sınıfının içindeki herhangi bir kod, herhangi bir Wallet nesnesinin private üyelerine erişebilir.
Tüm parasal değerleri <iomanip> başlığındaki std::fixed ve std::setprecision(2) kullanarak iki ondalık basamakla biçimlendir. Bakiye girdilerini std::stod() kullanarak dönüştür.
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: Girdi değerleriyle iki Wallet nesnesi oluştur
// TODO: combinedBalance() kullanarak toplam varlığı yazdır
// Biçim: "Combined wealth: $<amount>"
// TODO: hasMoreThan() kullanarak cüzdanları karşılaştır ve kimin daha çok parası olduğunu yazdır
// Biçim: "<name> has more money"
// TODO: transferTo() kullanarak ilk cüzdandan ikinciye 100.0 aktar
// TODO: "After transfer:" yazdır
// TODO: Toplam varlığı yeniden yazdır
// TODO: Yeniden karşılaştır ve kimin daha çok 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
1Nesne Yönelimli Programlamanın Temelleri
Harici DosyalarC++ Derleme ve Derleme SüreciHeader Dosyaları ve Kaynak DosyalarıNamespace'ler ve KapsamC++'ta Nesne Yönelimli Programlamaya GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriTekrar - Basit Hesap Makinesi4Sınıf Özellikleri
Nesne ve Statik ÜyelerGetter ve Setter'larconst Üye Fonksiyonlarımutable Anahtar SözcüğüStatik 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 DüzeyleriCtor ve Dtor Çağrı SırasıMetot Geçersiz KılmaVirtual Fonksiyonlar ve VTableÇoklu KalıtımVirtual KalıtımÖzet - Çalışan Hiyerarşisi2Bellek Yönetimi
Stack ve Heap Belleğiİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++’ta Akıllı İşaretçilerC++’ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'ta Erişim BelirleyicileriErişim Belirleyicilerine Derinlemesine BakışBilgi GizlemeStruct ve Class Karşılaştırmasıİç İçe ve İç SınıflarTekrar - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme Zamanı 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ıDinamik Tür Dönüştürme ve RTTITekrar - Şekil Hesaplayıcı11İleri Düzey OOP Kavramları
Bileşim ve KalıtımCRTP ile Mixin'lerPimpl İdiomuTür SilmeEnum Sınıfları ve Güçlü TürlemeOOP'de İstisna YönetimiÖzel İstisna Hiyerarşileri14Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıBileşik KalıpBir Kalıp Olarak RAII3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopyalama YapıcısıTaşıma YapıcısıYapıcı Başlatma ListeleriYönlendiren YapıcılarYıkıcıları Derinlemesine İncelemeÜç / 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örleri Aşırı YüklemeKarşılaştırma Operatörlerini Aşırı YüklemeAkış OperatörleriAtama Operatörünü Aşırı Yükleme[] ve () Operatörlerini Aşırı YüklemeTür Dönüşüm OperatörleriTekrar - Matrix Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeDeğişken Sayıda Argüman Alan ŞablonlarSFINAE ve Tür Özelliklerinin TemelleriTekrar: Genel Amaçlı KapsayıcıKendi başına pratik yap: Online C++ derleyicisi