... или «...обещаю, для тебя — никакой разницы. Ничего не изменится...»
Простое правило: если логическое состояние объекта после выполнения метода останется неизменным, то смело объявляйте его (метод) константным, а физически изменяющиеся переменные-члены класса объявляйте со спецификатором mutable.
Кстати, mutable можно применять только к нестатическим переменным-членам, что логично.
Для клиента класса не важно, изменили ли вы какую-нибудь переменную, которая для него ничего не значит. Для него важно, чтобы объект был тем же, чем был до этого, с логической точки зрения. И так, ещё раз: всегда предпочитайте физической константности логическую. И выбросьте из головы, что применение mutable — признак непрофессиональности. Это ложное наставление неопытных и глупых программистов. Все признанные мастера советуют и рекомендуют пользоваться mutable. Пример дальше.
...В этом примере описан класс, содержащий метод, возвращающий какое-то целочисленное значение. Представим, что это целочисленное значение вычисляется очень сложным и ресурсоёмким методом. Потому, вычисление этого значения не выполняется при инициализации объекта, а только по запросу (отложенное вычисление):
class AverageFoodConsumption final {
public:
int getAverage() const {
if (!calculated_) {
avg_ = calculateAverage();
calculated_ = true;
}
return avg_;
}
private:
int calculateAverage() const {
// Открыть Базу данных или файл, рассчитать
// различные типы пищи, её потребление, высчитать
// какой-то общий коэффициент и вернуть его.
}
private:
mutable bool calculated_;
mutable int avg_;
};
Метод getAverage объявлен константным. Обе переменные, объявленные в классе, в нём модифицируются, потому их мы объявляем, используя спецификатор mutable. Объект вычисляет требуемое от него значение во время первого запроса. И всё — в дальнейшем целочисленное значение просто возвращается.