user870130
user870130

Reputation: 575

Const Member Function

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.

Upvotes: 0

Views: 2651

Answers (2)

Mats Petersson
Mats Petersson

Reputation: 129314

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.

Upvotes: 3

tofi9
tofi9

Reputation: 5853

What does the const keyword behind a method declaration guarantee?

The guaranty is a contractual reminder, rather than 'physical' memory barrier.

Thus, if you implement the const keyword correctly, the compiler will be able to help you to detect possible bugs.

However, no C/C++ compiler will stop you from modifying the member state directly; neither via fields nor by casting the object reference to a pointer and modifying the underlying memory.

Is my const method allowed to change (local/global) state?

A const method is not allowed to change the external behaviour of the system, but it is perfectly acceptable for a const method to change the internal state.

In other words, after calling all const methods randomly a couple of times, the system should still provide the same behaviour it did initially.

On the other hand, if the const method feels like caching a time consuming calculation and reuse it for the next call, it should be allowed. Same goes for a logger class that logs statistics, but does not change the behaviour of the system.

Upvotes: 2

Related Questions