Mutable Anahtar Kelimesi
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 30 / 104.
Sabit (const) üye fonksiyonların herhangi bir üye değişkeni değiştiremeyeceğini öğrendiniz. Ancak bazen, bir önbellek veya erişim sayacı gibi, nesnenin mantıksal durumunu etkilemeyen bir üyeyi değiştirmeniz gerekebilir. mutable anahtar kelimesi, const kısıtlamasına bir istisna sağlar.
mutable bir üye, const bir üye fonksiyonun içinde bile değiştirilebilir:
class DataFetcher {
std::string data;
mutable int accessCount; // const fonksiyonlarda değiştirilebilir
public:
DataFetcher(std::string d) : data(d), accessCount(0) {}
std::string getData() const {
accessCount++; // accessCount mutable olduğu için izin verilir
return data;
}
int getAccessCount() const {
return accessCount;
}
};mutable olmadan, const fonksiyonu getData() içinde accessCount değerini artırmak bir derleyici hatasına neden olur. mutable anahtar kelimesi derleyiciye şunu söyler: "Bu üyenin, nesne const olarak kabul edildiğinde bile değişmesine izin verilir."
mutable için yaygın kullanım durumları arasında hesaplanmış değerlerin önbelleğe alınması, erişim istatistiklerinin takibi ve mutex'ler gibi senkronizasyon ilkel öğeleri yer alır. Her durumda, yapılan değişiklik nesnenin mantıksal olarak temsil ettiği şeyi değiştirmez; önbelleğe alınmış bir değer yalnızca bir optimizasyondur ve bir erişim sayacı kullanım hakkındaki meta veridir.
class Circle {
double radius;
mutable double cachedArea;
mutable bool areaCached;
public:
double getArea() const {
if (!areaCached) {
cachedArea = 3.14159 * radius * radius;
areaCached = true;
}
return cachedArea;
}
};mutable anahtar kelimesini idareli kullanın - bu yalnızca nesnenin gözlemlenebilir durumunu etkilemeyen üyelere uygulanmalıdır.
Görev
KolayBir belgenin kaç kez görüntülendiğini, salt okunur metotlarımızın const-doğruluğunu (const-correctness) bozmadan takip eden bir belge görüntüleyici oluşturalım. Bu, mutable anahtar kelimesi için mükemmel bir kullanım örneğidir.
Kodunuzu düzenlemek için iki dosya oluşturacaksınız:
Document.h: İçeriği depolayan ve görüntüleme istatistiklerini gizlice takip eden birDocumentsınıfı tanımlayın. Sınıfınız şunlara ihtiyaç duyar:- Özel (private) üyeler:
title(string),content(string) ve const metotlarda bile değiştirilebilen birmutable int viewCount - Bir başlık ve içerik alan,
viewCountdeğerini0olarak başlatan bir yapıcı (constructor) - Başlığı döndüren bir
getTitle()const metodu viewCountdeğerini artıran (mutable olduğu için izin verilir) ve içeriği döndüren birgetContent()const metodu- İçeriğe kaç kez erişildiğini döndüren bir
getViewCount()const metodu - İçeriğin ilk 20 karakterini ve ardından
"..."döndüren birgetPreview()const metodu — bu sadece bir önizleme olduğu için görüntüleme sayısını artırmamalıdır
- Özel (private) üyeler:
main.cpp: Mutable anahtar kelimesinin, metotları mantıksal olarak const tutarken erişim istatistiklerini takip etmeye nasıl izin verdiğini gösterin. Girişten bir belge başlığı ve içeriği okuyun (her biri ayrı bir satırda), ardından:- Giriş değerleriyle bir
Documentoluşturun "Title: <title>"yazdırın"Preview: <preview>"yazdırın"Views after preview: <count>"yazdırıngetContent()kullanarak tam içeriğe erişin ve"Content: <content>"yazdırın"Views after first read: <count>"yazdırın- İçeriğe tekrar erişin ve
"Content: <content>"yazdırın "Views after second read: <count>"yazdırın"[Const Access] <title>: <content>"yazdıran birvoid displayDocument(const Document& doc)yardımcı fonksiyonu oluşturun — bu, const metotlarımızın const referanslarla çalıştığını kanıtlar- Belgenizle
displayDocument()fonksiyonunu çağırın "Final view count: <count>"yazdırın
- Giriş değerleriyle bir
Görüntüleme sayısı önizlemeden sonra 0 olmalı (çünkü önizlemeler tam görüntüleme sayılmaz), ardından getContent() her çağrıldığında artmalıdır. Mutable anahtar kelimesi bunu mümkün kılar — o olmasaydı, viewCount değerini getContent() gibi const metotların içinde değiştiremezdiniz.
Eğer içerik 20 karakterden kısaysa, getPreview() tüm içeriği ve ardından "..." döndürmelidir.
Kopya kağıdı
mutable anahtar kelimesi, bir üye değişkenin const üye fonksiyonlar içinde bile değiştirilmesine olanak tanır:
class DataFetcher {
std::string data;
mutable int accessCount; // const fonksiyonlarda değiştirilebilir
public:
DataFetcher(std::string d) : data(d), accessCount(0) {}
std::string getData() const {
accessCount++; // accessCount mutable olduğu için izin verilir
return data;
}
int getAccessCount() const {
return accessCount;
}
};mutable olmadan, bir const fonksiyon içinde bir üye değişkeni değiştirmek derleyici hatasına neden olur. Bu anahtar kelime derleyiciye, nesne const olarak kabul edilse bile bu üyenin değişmesine izin verildiğini söyler.
Yaygın kullanım durumları arasında hesaplanan değerlerin önbelleğe alınması, erişim istatistiklerinin takibi ve senkronizasyon ilkel öğeleri yer alır. Yapılan değişiklik, nesnenin mantıksal olarak neyi temsil ettiğini değiştirmemelidir:
class Circle {
double radius;
mutable double cachedArea;
mutable bool areaCached;
public:
double getArea() const {
if (!areaCached) {
cachedArea = 3.14159 * radius * radius;
areaCached = true;
}
return cachedArea;
}
};mutable anahtar kelimesini idareli kullanın - yalnızca nesnenin gözlemlenebilir durumunu etkilemeyen üyeler için.
Kendin dene
#include <iostream>
#include <string>
#include "Document.h"
using namespace std;
// TODO: displayDocument fonksiyonunu uygulayın
// Şunu yazdırmalıdır: "[Const Access] <title>: <content>"
void displayDocument(const Document& doc) {
// TODO: Bu fonksiyonu uygulayın
}
int main() {
// Girdiyi oku
string title;
string content;
getline(cin, title);
getline(cin, content);
// TODO: Girdi değerleriyle bir Document oluşturun
// TODO: "Title: <title>" yazdırın
// TODO: "Preview: <preview>" yazdırın
// TODO: "Views after preview: <count>" yazdırın
// TODO: Tam içeriğe erişin ve "Content: <content>" yazdırın
// TODO: "Views after first read: <count>" yazdırın
// TODO: İçeriğe tekrar erişin ve "Content: <content>" yazdırın
// TODO: "Views after second read: <count>" yazdırın
// TODO: Belgenizle displayDocument() fonksiyonunu çağırın
// TODO: "Final view count: <count>" yazdırın
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