Ключевое слово mutable
Ключевое слово mutable применяется к нестатическим полям класса
и позволяет изменять их значение даже в том случае, когда объект
объявлен как const, либо когда изменение происходит внутри
константного метода. Обычно mutable используют для полей,
которые не влияют на логическое состояние объекта: кэш, счётчики
вызовов, отладочная информация, мьютексы синхронизации.
Ключевое слово указывается перед типом поля в объявлении класса.
Оно не является частью интерфейса и не может быть применено
к статическим полям, ссылкам или полям, объявленным как const.
Синтаксис
class ClassName
{
mutable тип имя_поля;
};
Пример
Давайте объявим класс Counter с полем-счётчиком,
которое помечено как mutable. Это позволит увеличивать
счётчик внутри константного метода getValue:
#include <iostream>
using namespace std;
class Counter
{
private:
int value;
mutable int calls;
public:
Counter(int v) : value(v), calls(0)
{
}
int getValue() const
{
calls++;
return value;
}
int getCalls() const
{
return calls;
}
};
int main()
{
Counter c(42);
cout << c.getValue() << endl;
cout << c.getValue() << endl;
cout << c.getCalls() << endl;
return 0;
}
Результат выполнения кода:
42
42
2
Пример
Теперь объявим объект класса Counter как const
и попробуем изменить обычное поле и поле с mutable.
Изменение обычного поля вызовет ошибку компиляции, а изменение
mutable-поля пройдёт успешно:
#include <iostream>
using namespace std;
class Counter
{
private:
int value;
mutable int calls;
public:
Counter(int v) : value(v), calls(0)
{
}
void reset() const
{
// value = 0; // ошибка: нельзя менять обычное поле
calls = 0;
}
int getValue() const
{
return value;
}
int getCalls() const
{
return calls;
}
};
int main()
{
const Counter c(100);
c.reset();
cout << c.getValue() << endl;
cout << c.getCalls() << endl;
return 0;
}
Результат выполнения кода:
100
0