Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I declare any method that can be const a const method

Simple question. Should I declare any method that can be const a const method? This includes methods that don't return any member variables, or return const references to member variables. Is there any reason not to do so (apart from the obvious reasons, which the compiler will point out anyway)?

like image 623
Samaursa Avatar asked Apr 18 '11 20:04

Samaursa


2 Answers

A non-const method cannot be called through a pointer to a constant object. So if method can be const, not declaring it const would impose artificial limits on its use.

Apart from that, making a method const is an important semantic detail to give the user a feeling of the effect that could be expected from calling it.

like image 138
Alexander Gessler Avatar answered Oct 19 '22 10:10

Alexander Gessler


It seems that I am to be the discording note here:

Should I declare any method that can be const a const method?

No, the decision should be taken at a different level, during design. You should mark as const all methods that semantically don't modify the object. This might include some methods that do actually modify some internal detail that is not part of the perceivable state of the object (and those attributes should be mutable) and it might not include some methods that do not change anything at all.

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;
};

In its current form, you cannot change the implementation, and change_impl is non-const, even if it does not modify any member attribute it is not marked as const, because semantically it does change.

On the other hand, the expensive_calculation() method does not semantically modify the state of the object, the perceivable state will be the same before and after the operation is called, but it does modify a cache attribute to speed up later calls (if the state has not changed). As such, the method is const, and the cache is mutable.

like image 39
David Rodríguez - dribeas Avatar answered Oct 19 '22 08:10

David Rodríguez - dribeas