Menu
Coddy logo textTech

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.

challenge icon

Görev

Kolay

Bir 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 bir Document sı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 bir mutable int viewCount
    • Bir başlık ve içerik alan, viewCount değerini 0 olarak başlatan bir yapıcı (constructor)
    • Başlığı döndüren bir getTitle() const metodu
    • viewCount değerini artıran (mutable olduğu için izin verilir) ve içeriği döndüren bir getContent() 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 bir getPreview() const metodu — bu sadece bir önizleme olduğu için görüntüleme sayısını artırmamalıdır
  • 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 Document oluşturun
    • "Title: <title>" yazdırın
    • "Preview: <preview>" yazdırın
    • "Views after preview: <count>" yazdırın
    • getContent() 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 bir void 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

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;
}
quiz iconKendini test et

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