I have a module that performs some calculations and during the calculations, communicates with other modules. Since the calculation module does not want to rely on the other modules, it exposes an interface like this (this is a very simplified version of course):
class ICalculationManager
{
public:
double getValue (size_t index) = 0;
void setValue (size_t index, double value) = 0;
void notify (const char *message) = 0;
};
Applications that want to use the calculation module need to write their own implementation of the interface, and feed it to the calculation tool, like this:
MyCalculationManager calcMgr;
CalculationTool calcTool (calcMgr);
calcTool.calculate();
I am wondering now whether it makes sense to add "const" to the methods of the ICalculationManager interface.
It would seem logical that the getValue method only gets something and doesn't change anything, so I could make this const. And setValue probably changes data so that won't be const. But for a more general method like notify I can't be sure.
In fact, for none of the methods I can now for sure that the method is really implemented as a const method, and if I would make the interface methods const, I am forcing all implementations to be const as well, which is possibly not wanted.
It seems to me that const methods only make sense if you know beforehand what your implementation will be and whether it will be const or not. Is this true?
Doesn't it make sense to make methods of this kind of interface const? And if it makes sense, what are good rules to determine whether the method should be const or not, even if I don't know what the implementation will be?
EDIT: changed the parameter from notify from "char *" to "const char *" since this lead to irrelevant answers.
You make a function const
when you are advertising to clients that calling the function will never change the externally visible state of the object. Your object only has one piece of state that can be retrieved, getValue.
So, if getValue can cause the next getValue to return a different value then sure, leave it non-const. If you want to tell clients that calling getValue() will never change the value returned by the next getValue() then make it const.
Same for notify:
double d1 = mgr->getValue(i);
mgr->notify("SNTH"); // I'm cheating.
double d2 = mgr->getValue(i);
assert(d1==d2);
If that should hold true for all cases and all i's then notify() should be const. Otherwise it should not be.
Yes. One should use const
whenever and wherever it is sensible to do so. It doesn't make sense that the method for performing a calculation (which is what your interface suggests) should change it's observable behavior because it had "notify" called on it. (And for that matter, how is notification related to calculation at all?)
My making one of the interface members const
, you don't force clients to be const
-- you merely allow them use of a const ICalculationManager
.
I would probably make Notify
const
. If clients need to do something non-const
as a result of a notification, then Notify
is not a good method name -- that name suggest non-state-modifying transformations such as logging, not modification.
For instance, most of the time you pass your interface around, you're going to want to use pass-by-reference-to-const to pass the interface implementor, but if the methods aren't const
, you cannot do that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With