The const member function guarantees that no member variables can be changed by the member function unless they are marked as mutable.
That being said it guarantees nothing else?
Here is a real example. I have a classes EventHandler
and EventDispatcher
.
class EventHandler
{
public:
void registerHandler(EventHandler* handler) const // Should this be a const?
{
EventDispatcher::registerHandler(handler);
}
};
EventDispatcher // Singleton Class
{
public:
void registerHandler(EventHandler* handler)
{
mListeners.push_back(handler);
}
private:
std::vector<EventHandler*> mListeners;
};
Should EventDispatcher
's registerHandler(EventHandler*)
be const? It does not change its member variables, but it does change global state.
Correct, it makes no guarantees about any other state than the object itself. And I would say that there's no particular requirement that it doesn't modify global state. [If you take it to extremes, any function call does modify the current state of the processor - even if it's just storing the return address on the stack [1]].
But a more reasonable thing would be that a const
member function like this:
class myclass
{
private:
std::vector<int> v;
public:
std::vector<int> getV() const { return v; }
};
This will create a copy of the vector v
- which in turn allocates memory (thus changing global state). An output function that feeds your object to a output stream would be a similar thing.
If a member function modifies some global state (in a way that isn't obvious), then it probably should be made clear in the description of the function (documentation is useful sometimes).
[1] Of course, the C++ and C standards do not state that the processor has to have a stack, return addresses, etc - the compiler could inline all the code, and not make any "calls" at all, or use magic to "remember" where to get back to - as long as the magic actually works, it's fine to rely on that.
Edit based on your edited question:
It's one of those that isn't entirely obvious in either direction, you would expect the registerHanlder
to do something like "store the handler object somewhere". But since it's not modifiying the object itself, it may help to explain that it's updating the dispatcher class. Of course, if it's not actually updating the class itself, or using anything from the class, you probably should make it static
rather than const
- that way it's clear that it's not actually modifying the object itself.
Aside: As it is written, your code won't work, since EventDispatcher::registerHandler
is not a static member, and your EventHandler::registerHandler
is not referring to an instance of EventDispatcher
. You would either have to make an instance of EventDispatcher
as a global variable, or make EventDispatcher::registerHandler
a static function and make mListeners
a static member. Or something else along those lines.