Должен ли я объявить любой метод, который может быть const const метод - PullRequest
6 голосов
/ 19 апреля 2011

Простой вопрос. Should I declare any method that can be const a const method? Это включает методы, которые не возвращают какие-либо переменные-члены или не возвращают константные ссылки на переменные-члены. Есть ли причина этого не делать (кроме очевидных причин, которые компилятор все равно укажет)?

Ответы [ 5 ]

13 голосов
/ 19 апреля 2011

Не- const метод не может быть вызван через указатель на постоянный объект. Таким образом, если метод может быть const, то, если он не объявлен как const, это накладывает искусственные ограничения на его использование.

Кроме того, создание метода const является важной семантической деталью, которая дает пользователю ощущение того эффекта, которого можно ожидать от его вызова.

6 голосов
/ 19 апреля 2011

Кажется, что я должен быть примечанием к записи здесь:

Должен ли я объявить любой метод, который может быть 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.

5 голосов
/ 19 апреля 2011

Да. Согласно Effective C ++, «используйте const, когда это возможно».

2 голосов
/ 19 апреля 2011

В одном случае я бы дважды подумал об использовании const: виртуальной функции базового класса.Возможно, хорошо, что унаследованные классы не могут быть изменены их переопределенной функцией, но некоторые разработчики могут не согласиться и из-за этого действительно вынуждены перепрыгивать через обручи.

2 голосов
/ 19 апреля 2011

Если метод не изменяет логическое состояние объекта, вы должны пометить методы как const. Это отличный сервис для клиентов ваших объектов, так как они могут быть использованы в полной мере при наличии константных ссылок / указателей.

...