Ленивые свойства — допустимое использование изменяемого?

Сегодня я обнаружил, что пишу немного кода, подобного следующему, и мне было интересно, является ли это правильным использованием mutable ключевое слово.

Идея в том, что я хочу получить доступ к некоторым свойствам через const указатель, но я хочу оценивать свойства только тогда, когда они мне нужны.

class Person {
public:
Person() : age(-1) {}
~Person() {}

int GetAge() const {
if( age == -1 ) { CalculateAge(); }
return age;
}

private:
mutable int age;

// Note: as a result of being called from a `const` method,
// CalculateAge has to be const itself.
void CalculateAge() const {
age = 33; // do calculation based on date of birth or whatever.
}
};

Это точка mutableИли я здесь злоупотребляю?
Я убедил себя в том, что концептуально приведенный выше код эквивалентен

class Person {
public:
Person() {}
~Person() {}

int GetAge() const {
// Always do the expensive calculation here
return 33;
}
};

или же

class Person {
public:
Person() {
// Do the expensive calculation here even if age is never used.
age = 33;
}
~Person() {}

int GetAge() const {
return age;
}

private:
int age; // non-mutable
};

где GetAge() правильно помечен как const; кеширует ли он результат на самом деле — это деталь реализации, которая не имеет отношения к клиенту моего класса.

Редактировать: Кроме того, мне было бы интересно услышать любые другие решения, которые не включаютconst,

1

Решение

mutable может использоваться, если вы хотите, чтобы метод был константным, поскольку он не изменяет внешнее состояние объекта, но вам все равно нужно изменить некоторое внутреннее состояние. На мой взгляд, это именно то, что у вас здесь. Отсроченный расчет возраста — это всего лишь внутренняя оптимизация, и разумно скрыть эту оптимизацию от пользователя. Пользователь не поймет, почему получение возраста изменяет объект (внешнее состояние).

Но: я не люблю изменчивых. Непостоянство может быть проблемой, если у вас есть объект const, который находится в постоянной памяти (например, отображение файлов только для чтения). Если затем вы вызовете метод const для этого объекта, компилятор не будет жаловаться. Но код потерпит крах, если вы измените какой-либо изменяемый объект.

1

Другие решения

Не полный ответ, но да, он выглядит и оскорбляет меня. Вы должны отметить mutable только члены, которые не изменяют внешнее состояние объекта. В вашем случае у вас есть метод GetAge который выставляет член age что означает, что изменение age изменяет «видимое» состояние объекта.

редактировать

После ваших правок я должен сказать, что все в порядке. Пока вы используете член age как cache,

1

По вопросам рекламы [email protected]