Mutable Anahtar Kelimesi
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 30 / 104.
const üye fonksiyonlarının hiçbir üye değişkenini değiştiremeyeceğini öğrendin. Ancak bazen nesnenin mantıksal durumunu etkilemeyen bir üyeyi (önbellek veya access sayacı gibi) değiştirmen gerekir. mutable anahtar sözcüğü, const kısıtlamasına bir istisna sağlar.
mutable bir üye, const üye fonksiyonu 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 işlevi getData() içinde accessCount değerini artırmak derleyici hatasına neden olur. mutable anahtar sözcüğü derleyiciye şunu söyler: "Nesne const olarak kabul edilse bile bu üyenin değişmesine izin verilir."
Değiştirilebilir yapıların yaygın kullanım alanları arasında hesaplanan değerleri önbelleğe alma, erişim istatistiklerini izleme ve mutex gibi senkronizasyon ilkelleri bulunur. 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 erişim sayacı kullanım hakkında meta verilerdir.
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 ifadesini ölçülü kullanın - yalnızca nesnenin gözlemlenebilir durumunu etkilemeyen üyelere uygulanmalıdır.
Görev
KolaySalt okunur yöntemlerimizin const-doğruluğunu bozmadan, bir belgenin kaç kez görüntülendiğini takip eden bir belge görüntüleyici oluşturalım. Bu, mutable anahtar sözcüğü için mükemmel bir kullanım alanıdır.
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 şunları içermelidir:- Özel üyeler:
title(string),content(string) ve const yöntemlerde bile değiştirilebilen birmutable int viewCount - Bir başlık ve içerik alan,
viewCountdeğerini0olarak başlatan bir kurucu - Başlığı döndüren bir
getTitle()const yöntemi viewCountdeğerini artıran (mutable olduğu için buna izin verilir) ve içeriği döndüren birgetContent()const yöntemi- İçeriğe kaç kez erişildiğini döndüren bir
getViewCount()const yöntemi - İçeriğin ilk 20 karakterini ve ardından
"..."ifadesini döndüren birgetPreview()const yöntemi. Bu yalnızca bir önizleme olduğundan görüntüleme sayısını artırmamalıdır
- Özel üyeler:
main.cpp: Yöntemleri mantıksal olarak const tutarken mutable'ın erişim istatistiklerini takip etmeyi nasıl sağladığını gösterin. Bir belge başlığını ve içeriğini girdiden okuyun (her biri ayrı bir satırda), ardından:- Girdi değerleriyle bir
Documentoluşturun "Title: <title>"ifadesini yazdırın"Preview: <preview>"ifadesini yazdırın"Views after preview: <count>"ifadesini yazdırıngetContent()kullanarak tam içeriğe erişin ve"Content: <content>"ifadesini yazdırın"Views after first read: <count>"ifadesini yazdırın- İçeriğe tekrar erişin ve
"Content: <content>"ifadesini yazdırın "Views after second read: <count>"ifadesini yazdırın"[Const Access] <title>: <content>"ifadesini yazdıranvoid displayDocument(const Document& doc)yardımcı işlevini oluşturun. Bu, const yöntemlerimizin const başvurularla çalıştığını kanıtlar- Belgenizle
displayDocument()işlevini çağırın "Final view count: <count>"ifadesini yazdırın
- Girdi değerleriyle bir
Önizlemeden sonra görüntüleme sayısı 0 olmalıdır (çünkü önizlemeler tam görüntüleme olarak sayılmaz), ardından getContent() her çağrıldığında artmalıdır. mutable anahtar sözcüğü bunu mümkün kılar; bu anahtar sözcük olmadan getContent() gibi const yöntemlerin içinde viewCount değerini değiştiremezdiniz.
İçerik 20 karakterden kısaysa, getPreview() tüm içeriği ve ardından "..." ifadesini döndürmelidir.
Kendin dene
#include <iostream>
#include <string>
#include "Document.h"
using namespace std;
// TODO: displayDocument fonksiyonunu uygula
// Şunu yazdırmalı: "[Const Access] <title>: <content>"
void displayDocument(const Document& doc) {
// TODO: Bu fonksiyonu uygula
}
int main() {
// Girdiyi oku
string title;
string content;
getline(cin, title);
getline(cin, content);
// TODO: Girdi değerleriyle bir Document oluştur
// TODO: "Title: <title>" yazdır
// TODO: "Preview: <preview>" yazdır
// TODO: Print "Views after preview: <count>"
// TODO: Tam içeriğe eriş ve "Content: <content>" yazdır
// TODO: Print "Views after first read: <count>"
// TODO: İçeriğe tekrar eriş ve "Content: <content>" yazdır
// TODO: Print "Views after second read: <count>"
// TODO: displayDocument() fonksiyonunu belgenizle çağır
// TODO: Print "Final view count: <count>"
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 KonteynerKendi başına pratik yap: Online C++ derleyicisi