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)?

- 16,527
- 21
- 89
- 160
-
Is there any harm in it? Do you have some reservations? – Gabe Apr 18 '11 at 20:07
-
@Gabe: Nope, just wanted assurance (you never know when somebody answers with a `"Yes, BUT in such and such scenario, you may not want to"`) ... I am getting used to const-correctness and thought I'd clear this up. – Samaursa Apr 18 '11 at 20:13
-
2possible duplicate of [When should a member function have a const qualifier and when shouldn't it?](http://stackoverflow.com/questions/2462964/when-should-a-member-function-have-a-const-qualifier-and-when-shouldnt-it) – Kirill V. Lyadvinsky Apr 18 '11 at 20:14
-
1There's a caveat: "can be const" should mean, "can be const by design" and not "will still compile if marked const in the current implementation". Extreme example - you could conceivably have a base class with a do-nothing implementation of some virtual function that can currently be made const. But of course you won't mark it const if future subclasses are expected to have non-const implementations. So it's not a mechanical process, "try to make it const, if that works leave it const", rather it's part of interface design and hence a negotiation between caller and callee. – Steve Jessop Apr 18 '11 at 23:28
5 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.

- 45,603
- 7
- 82
- 122
-
4Also note the (important) difference between physical constness and logical constness. So this article for more details: http://drdobbs.com/cpp/184403892. – AVH Apr 18 '11 at 20:14
-
@unapersson: The semantics of a `const` method do not allow you to modify the contained pointer, but they won't inhibit you from changing the pointed data, so a `const` method can modify some state of the object in ways that the compiler will not flag if the class contains pointers. `struct test { int *p; test() : p( new int() ) {} ~test() { delete p; } int* getP() const { return p; } };` is correct, and allows `int main() { test t; *t.getP() = 10; }` that changes the value stored in the class. That is `const`-ness is a one level property, and it is up to the user to resolve deeper levels. – David Rodríguez - dribeas Apr 19 '11 at 07:39
-
Which can be done in some cases: `int const * getP() const { return p; }` would return not a copy of the pointer, but one pointer to a constant integer, and in that way, the caller will not be able to modify your object. The same goes with references, if you store a reference to a mutable object, that object is not (syntactically) belong to your object, so you can return mutable references that refer to that object from a constant member function, potentially allowing user code to manipulate your internals. – David Rodríguez - dribeas Apr 19 '11 at 07:42
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
.

- 204,818
- 23
- 294
- 489
-
1This is correct IMO. Some functions may not alter class data in current implementation, but logically they could. I just wrote a socket cleanup function that closes a SOCKET and nothing else, so it could be const, but maybe in the future I'll have a `bool isSocketOpen` to change. – rotanimod Apr 18 '11 at 20:41
-
(+1) The point about making a decision during design phase is a very good one, I think, but I still think it doesn't answer the exact question - the OP asked about methods that *can* be declared `const`, so using `mutable` to be able to declare otherwise non-const methods `const` is not relevant at all. – Alexander Gessler Apr 18 '11 at 21:08
-
The same about vitual methods to be implemented by deriving classes in a manner that might modify the object. If you know that you will have an implementation that will need the method to be non-const, then the virtual prototype in the base class cannot be declared `const` in the first place so the question that is asked here never arises. – Alexander Gessler Apr 18 '11 at 21:08
-
@Alexander Gessler: I do think it is quite relevant. In the case of the `mutable` member, `mutable` is the *result* of the method being `const`, not the other way around. That is, no one writes `mutable` sparingly, but rather as result of the design decision that makes a method constant, and yet that attribute needs to be modified. If you start with `class test { std::pair
cache; int a,b; ...` the operation *cannot* be made `const`, as it needs to modify `cache`. And yet, semantically it does not, so you mark it `const`, the compiler complains and you mark `cache` as `mutable`. – David Rodríguez - dribeas Apr 19 '11 at 07:47 -
Again, in the case of the virtual function, as it is, and without any other classes, you *can* make it `const` from the language point of view, but not from the design point of view: yes, it is true that it does not modify any member (currently), but if you mark it `const` then you will run into problems later. Now, if you are saying that *after carefully designing you should mark all things that in your design are const as `const`*, you are completely right. But I have seen many people remove the `const` in the cache case because the compiler complaint, so I think it's important to know. – David Rodríguez - dribeas Apr 19 '11 at 07:50
Yes. According to Effective C++, "use const whenever possible".

- 14,912
- 10
- 45
- 81
-
1Tempted to +1, but held back because "someone says so" isn't a reason, however reliable and respected the someone may be. – Apr 18 '11 at 20:10
-
Without a further definition of *whenever possible* I cannot upvote. That is as much as answering the question with the exact same question: *when should it not be const?* – David Rodríguez - dribeas Apr 18 '11 at 20:30
-
That wasn't his question. His question was "are there any specific cases when you shouldn't make something const even though you can". – Andrew Rasmussen Apr 18 '11 at 22:46
-
I provided one example in my answer: a virtual method that might be overridden to modify part of the state, but that does not in the current implementation. In the base it could be `const`, but that would limit extensibility of the class or drive you into a nightmare of `mutable` members that should not be mutable, and are suddenly open to modification in all other `const` methods... – David Rodríguez - dribeas Apr 19 '11 at 07:53
If a method does not modify the logical state of the object, then you should mark the methods as const. This is a great service to the clients of your objects, as they can then be used to the fullest extent, given const references/pointers.

- 4,839
- 3
- 28
- 51
There is 1 case where I would think twice about using const: a base class virtual function. It might be a good thing that inherited classes can't be changed by their overridden function, but some developers might disagree and really have to jump through hoops because of this.

- 14,072
- 2
- 31
- 53