Должен ли я объявить любой метод, который может быть const const метод
Простой вопрос Should I declare any method that can be const a const method?
Это включает в себя методы, которые не возвращают никаких переменных-членов или возвращают константные ссылки на переменные-члены. Есть ли причина не делать этого (кроме очевидных причин, которые компилятор укажет в любом случае)?
5 ответов
Неconst
метод не может быть вызван через указатель на постоянный объект. Так что, если метод может быть const
, не объявляя это const наложит искусственные ограничения на его использование.
Помимо этого, делая метод const
является важной семантической деталью, чтобы дать пользователю ощущение того эффекта, который можно ожидать от его вызова.
Кажется, что я должен быть примечанием к записи здесь:
Должен ли я объявить любой метод, который может быть 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
,
Да. Согласно Effective C++, "используйте const, когда это возможно".
В одном случае я бы дважды подумал об использовании const: виртуальной функции базового класса. Возможно, было бы хорошо, что унаследованные классы не могут быть изменены их переопределенной функцией, но некоторые разработчики могут не согласиться с ними и действительно вынуждены перепрыгивать через обручи из-за этого.
Если метод не изменяет логическое состояние объекта, вы должны пометить методы как const. Это отличный сервис для клиентов ваших объектов, так как они могут быть использованы в полной мере при наличии константных ссылок / указателей.