Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I declare these methods const?

I'm working on some C++ code where I have several manager objects with private methods such as

void NotifyFooUpdated();

which call the OnFooUpdated() method on the listeners of this object.

Note that they don't modify the state of this object, so they could technically be made const methods, even though they typically modify the state of the system as a whole. In particular, the listener objects might call back into this object and modify it.

Personally I'd like to leave them as they are and not declare them const.

However, our static code checker QAC flags this as a deviation, so I either have to declare them const, or I have to argue why they should stay non-const and get a grant for the deviation.

What are arguments for not declaring these methods const?
Or should I follow QAC and declare them const?
Should I adopt a strictly local viewpoint restricted to this object, or consider the system as a whole?

like image 884
starblue Avatar asked Oct 19 '10 12:10

starblue


People also ask

When should a method be const?

A function becomes const when the const keyword is used in the function's declaration. The idea of const functions is not to allow them to modify the object on which they are called. It is recommended practice to make as many functions const as possible so that accidental changes to objects are avoided.

How do you declare a const method?

To declare a constant member function, place the const keyword after the closing parenthesis of the argument list. The const keyword is required in both the declaration and the definition.

Why are const methods necessary C++?

class function const is used to tell the compiler that a class function will not change a member variable. Thus, a constant object of that type can safely call it.

What does const mean in a method?

Const (constant) in programming is a keyword that defines a variable or pointer as unchangeable. A const may be applied in an object declaration to indicate that the object, unlike a standard variable, does not change. Such fixed values for objects are often termed literals.


2 Answers

Loosely speaking you have a container class: A manager full of observers. In C and C++ you can have const containers with non-const values. Consider if you removed one layer of wrapping:

list<Observer> someManager;

void NotifyFooUpdated(const list<Observer>& manager) { ... }

You would see nothing strange about a global NotifyFooUpdated taking a const list, since it does not modify the list. That const argument actually makes the argument parsing more permissive: The function accepts both const and non-const lists. All the const annotation on the class method version means is const *this.

To address another perspective:

If you can't guarantee that the object you invoked the function on remains the same before and after the function call, you should generally leave that as non-const.

That's only reasonable if the caller has the only reference to the object. If the object is global (as it is in the original question) or in a threaded environment, the constness of any given call does not guarantee the state of the object is unchanged across the call. A function with no side-effects and which always returns the same value for the same inputs is pure. NotifyFooUpdate() is clearly not pure.

like image 100
Ben Jackson Avatar answered Sep 28 '22 02:09

Ben Jackson


If the listeners are stored as a collection of pointers you can call a non-const method on them even if your object is const.

If the contract is that a listener may update its state when it gets a notification, then the method should be non-const.

You are saying that the listener may call back into the object and modify it. But the listener will not change itself - so the Notify call could be const but you pass a non-const pointer to your own object into it.

If the listener already has that pointer (it listens only to one thing) then you can make both the methods const, as your object getting modified is a side-effect. What is happening is:

A calls B B modifies A as a result.

So A calling B leads indirectly to its own modification but is not a direct modification of self.

If this is the case both your methods could and probably should be const.

like image 29
CashCow Avatar answered Sep 28 '22 03:09

CashCow