Кажется, что я должен быть примечанием к записи здесь:
Должен ли я объявить любой метод, который может быть const метод const?
Нет, решение должно приниматься на другом уровне, во время проектирования. Вы должны пометить как const
все методы, которые семантически не изменяют объект. Это может включать в себя некоторые методы, которые действительно изменяют некоторые внутренние детали, которые не являются частью воспринимаемого состояния объекта (и эти атрибуты должны быть mutable
), и могут не включать некоторые методы, которые не изменяются вообще ничего.
enum impl { // different implementations of the algorithm
one_implementation,
another_implementation
};
class example {
mutable std::pair<bool, int> cache;
protected:
int a, b;
public:
example( int a, int b ) : cache(), a(a), b(b) {}
virtual ~example() {}
void set( int _a, int _b ) {
cache.first = false; // invalidate previous result
a = _a;
b= _b;
}
int expensive_calculation() const {
if ( !cache.first ) {
cache.second = calculate();
cache.first = true;
}
return cache.second;
}
virtual void change_impl( impl x ) {}
private:
virtual int calculate() const = 0;
};
В его текущей форме вы не можете изменить реализацию, и change_impl
не является константным, даже если он не изменяет какой-либо атрибут члена, он не помечен как const
, поскольку семантически это действительно меняется.
С другой стороны, метод expensive_calculation()
не семантически не изменяет состояние объекта, воспринимаемое состояние будет одинаковым до и после вызова операции, но оно изменяет cache
атрибут для ускорения последующих звонков (если состояние не изменилось). Таким образом, метод const
, а кеш mutable
.