Kata kunci mutable
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan C++ di Coddy. Pelajaran 30 dari 104.
Kamu sudah mempelajari bahwa fungsi anggota const tidak dapat mengubah variabel anggota apa pun. Namun, terkadang kamu perlu mengubah anggota yang tidak memengaruhi keadaan logis object, seperti cache atau penghitung akses. Kata kunci mutable memberikan pengecualian terhadap batasan const.
Member yang mutable dapat diubah bahkan di dalam fungsi member const:
class DataFetcher {
std::string data;
mutable int accessCount; // Bisa diubah dalam fungsi const
public:
DataFetcher(std::string d) : data(d), accessCount(0) {}
std::string getData() const {
accessCount++; // Diizinkan karena accessCount bersifat mutable
return data;
}
int getAccessCount() const {
return accessCount;
}
};Tanpa mutable, menambah nilai accessCount di dalam fungsi const getData() akan menyebabkan error kompilator. Kata kunci mutable memberi tahu kompilator: "Member ini boleh berubah meskipun object dianggap const."
Penggunaan umum untuk mutable mencakup menyimpan nilai hasil perhitungan dalam cache, melacak statistik akses, dan primitive sinkronisasi seperti mutex. Dalam setiap kasus, perubahan tersebut tidak mengubah representasi logis object, nilai yang disimpan dalam cache hanyalah optimasi, dan penghitung akses adalah metadata tentang penggunaan.
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;
}
};Gunakan mutable secukupnya, hanya pada anggota yang tidak memengaruhi status object yang dapat diamati.
Tantangan
MudahMari buat penampil dokumen yang melacak berapa kali dokumen telah dilihat, tanpa merusak const-correctness pada method yang hanya membaca data. Ini adalah penggunaan yang tepat untuk kata kunci mutable.
Kamu akan membuat dua file untuk mengatur kodemu:
Document.h: Definisikan classDocumentyang menyimpan konten dan diam-diam melacak statistik penayangan. Class-mu memerlukan:- Member private:
title(string),content(string), danmutable int viewCountyang dapat diubah bahkan di dalam method const - Konstruktor yang menerima title dan content, lalu menginisialisasi
viewCountmenjadi0 - Method const
getTitle()yang mengembalikan title - Method const
getContent()yang menaikkan nilaiviewCount(diizinkan karena variabel ini mutable) dan mengembalikan content - Method const
getViewCount()yang mengembalikan berapa kali content telah diakses - Method const
getPreview()yang mengembalikan 20 karakter pertama dari content, diikuti"...". Method ini TIDAK boleh menaikkan jumlah penayangan karena hanya menampilkan pratinjau
- Member private:
main.cpp: Tunjukkan bagaimana mutable memungkinkan pelacakan statistik akses sambil menjaga method tetap const secara logis. Baca title dan content dokumen dari input (masing-masing pada baris terpisah), lalu:- Buat
Documentdengan nilai input - Cetak
"Title: <title>" - Cetak
"Preview: <preview>" - Cetak
"Views after preview: <count>" - Akses seluruh content menggunakan
getContent()dan cetak"Content: <content>" - Cetak
"Views after first read: <count>" - Akses content lagi dan cetak
"Content: <content>" - Cetak
"Views after second read: <count>" - Buat fungsi pembantu
void displayDocument(const Document& doc)yang mencetak"[Const Access] <title>: <content>". Ini membuktikan bahwa method const kita berfungsi dengan referensi const - Panggil
displayDocument()dengan dokumenmu - Cetak
"Final view count: <count>"
- Buat
Jumlah penayangan harus 0 setelah pratinjau (karena pratinjau tidak dihitung sebagai penayangan penuh), lalu bertambah setiap kali getContent() dipanggil. Kata kunci mutable memungkinkan hal ini. Tanpanya, kamu tidak dapat mengubah viewCount di dalam method const seperti getContent().
Jika content lebih pendek dari 20 karakter, getPreview() harus mengembalikan seluruh content diikuti "...".
Coba sendiri
#include <iostream>
#include <string>
#include "Document.h"
using namespace std;
// TODO: Implementasikan fungsi displayDocument
// Fungsi ini harus mencetak: "[Const Access] <title>: <content>"
void displayDocument(const Document& doc) {
// TODO: Implementasikan fungsi ini
}
int main() {
// Baca input
string title;
string content;
getline(cin, title);
getline(cin, content);
// TODO: Buat Document dengan nilai input
// TODO: Cetak "Title: <title>"
// TODO: Cetak "Preview: <preview>"
// TODO: Cetak "Views after preview: <count>"
// TODO: Akses seluruh konten dan cetak "Content: <content>"
// TODO: Cetak "Views after first read: <count>"
// TODO: Akses konten lagi dan cetak "Content: <content>"
// TODO: Cetak "Views after second read: <count>"
// TODO: Panggil displayDocument() dengan dokumenmu
// TODO: Cetak "Final view count: <count>"
return 0;
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar-Dasar OOP
File EksternalBuild dan Kompilasi C++File Header dan File SourceNamespace dan CakupanPengantar OOP dalam C++class vs objectPointer 'this'method (Fungsi Anggota)Atribut (Anggota Data)Dasar Ctor dan DtorRingkasan: Kalkulator Sederhana4Properti class
Anggota instance vs staticGetter dan setterFungsi anggota constKata kunci mutableMethod dan variabel staticFungsi dan class friendRangkuman, Pengelola Rekening Bank7Pewarisan
Pewarisan DasarTingkat Akses pada PewarisanUrutan Pemanggilan Ctor & DtorPenimpaan methodFungsi Virtual & VTablePewarisan BergandaPewarisan VirtualRangkuman: Hierarki Karyawan2Manajemen Memori
Memori Stack vs HeapPointer dan ReferenceMemori Dinamis (new/delete)Smart Pointer di C++RAII di C++Rangkuman: Pengelola Array Dinamis5Enkapsulasi
Penentu Akses dalam C++Penentu Akses secara MendalamPenyembunyian Informasistruct vs classNested dan Inner classRangkuman, Sistem Catatan Siswa8Polimorfisme
Polimorfisme saat Compile vs RuntimeOverloading FungsiMeninjau Kembali Fungsi VirtualFungsi Virtual MurniKelas AbstrakDesain Interface di C++Casting Dinamis & RTTIRangkuman: Kalkulator Bentuk3Konstruktor & Destruktor
Konstruktor DefaultKonstruktor BerparameterKonstruktor SalinKonstruktor PindahDaftar Inisialisasi KonstruktorKonstruktor DelegasiKupas Tuntas DestruktorAturan Tiga, Lima, dan NolRangkuman: class String6Overloading Operator
Pengantar Overloading OperatorOverloading Operator AritmetikaOverloading Operator PerbandinganOperator StreamOverloading Operator PenugasanOverloading Operator [] dan ()Operator Konversi TipeRingkasan, class Matrix9Template
Template FungsiTemplate classSpesialisasi TemplateTemplate VariadikDasar SFINAE & Type TraitsRangkuman, Container GenerikLatihan sendiri: Compiler C++ online