How to call a non-const function within a const function (C++)
Solution 1
you should alter your program to use/declare const correctly...
one alternative is to use const_cast.
Solution 2
int Random() const
{
return var_ ? const_cast<ClassType*>(this)->newCall(4) : 0;
}
But it's not a good idea. Avoid if it's possible!
Solution 3
const_cast<MyClass *>(this)->newCall(4)
Only do this if you're certain newCall will not modify "this".
Solution 4
There are two possibilities here. First, newCall
and ALL of its callees are in fact non-modifying functions. In that case you should absolutely go through and mark them all const
. Both you and future code maintainers will thank you for making it much easier to read the code (speaking from personal experience here). Second, newCall
DOES in fact mutate the state of your object (possibly via one of the functions it calls). In this case, you need to break API and make Random
non-const to properly indicate to callers that it modifies the object state (if the modifications only affect physical constness and not logical constness you could use mutable attributes and propagate const
).
Related videos on Youtube
Grammin
Updated on July 09, 2022Comments
-
Grammin almost 2 years
I have a legacy function that looks like this:
int Random() const { return var_ ? 4 : 0; }
and I need to call a function within that legacy code so that it now looks like this:
int Random() const { return var_ ? newCall(4) : 0; }
The problem is that I'm getting this error:
In member function 'virtual int Random() const': class.cc:145: error: passing 'const int' as 'this' argument of 'int newCall(int)' discards qualifiers
Now I know in order to fix this error I can make my
newCall()
a const function. But then I have several funciton calls innewCall()
that I have to make, so now I would have to make all of those function calls const. And so on and so forth until eventually I feel like half my program is going to be const.My question: is there any way to call a function within Random() that isn't const? Or does anyone have any ideas on how to implement
newCall()
withinRandom()
without making half my program const.Thanks
-josh
-
GWW over 13 yearsYou could make Random() non-const.
-
Grammin over 13 yearsI would like to but Random() is legacy code that I can't really touch.
-
Martin York over 13 yearsIs that 4 chosen with an unbiased dice (thus making it really random).
-
davka over 13 yearslooking at the error message, I wander perhaps your problem is elsewhere? Note the "passing const int as 'this'". Sounds weird perhaps the 4 argument is interpreted as
this
? why? -
David Rodríguez - dribeas over 13 yearsThe question is not how many functions will have to be declared
const
, but whether those functions are actuallyconst
: do they modify any member of the object? If not, then mark them as const.
-
-
Grammin over 13 yearsIt's not a random number generator I just needed an example for SO. Thank you though
-
Martin York over 13 yearsUsing const_cast incorrectly (which is what will happen hear) will lead to a complete disaster.
-
Grammin over 13 yearsThanks for the advice, I ended up changing the functions below newCall() and newCall() to all be const, because I didn't want to use const incorrectly.
-
justin over 13 years@Grammin you're welcome. declaring it correctly has a lot of benefits. the most important (imo) is that it saves a ton of time in maintenance and readability. the compiler may quickly detect improper usage when the program changes. a side effect is that c++ starts to have so many consts written, that you think it would be nice if const were the default in some cases, and that a keyword was used to specify mutation instead :)
-
Janosimas about 9 yearsThere is another way, using a proxy. stackoverflow.com/questions/8325400/…
-
thatWiseGuy over 8 yearsLike you said, if you really need to use
const_cast
to accomplish this, try to refactor your design. -
Vaillancourt almost 7 years"one alternative is to use const_cast."... How should they use
const_cast
? -
justin almost 7 years@AlexandreVaillancourt The point I make in my answer is that "you should alter your program to use/declare
const
correctly...". Usingconst_cast
in the OP's scenario is an alternative which can be used to removeconst
fromthis
. The implication I made 6 years ago (and today) is that you should not useconst_cast
to accomplish this because a) It will be confusing and incorrect and b) It can result in Undefined Behavior. Good examples of when to useconst_cast
is to introduceconst
or modifyconst
,volatile
,__unaliged
qualifiers (in cases you know it is safe and legal). -
justin almost 7 years@AlexandreVaillancourt If you just want example usage, here it is: docs.microsoft.com/en-us/cpp/cpp/const-cast-operator -- Avoid erasing const where possible and understand what qualifies as UB. Certainly,
const_cast
is superior to C style casting -- when you (truly) need it. The cases when you need it should be quite rare when dealing with well written, modern APIs. I primarily use it when dealing with C APIs. Fortunately, I don't have to use it often. Finally, the line I don't recommend would look like this:return var_ ? const_cast<TYPE*>(this)->newCall(4) : 0;
. -
Zennichimaro over 5 yearssometimes you can't help it.. the previous programmer over-designed, used all the fancy features in the language, and then left the company after his code gets too messy and unmaintainable..
-
avtomaton over 3 yearsFinally the reasonable answer instead of 'you must not do that'... There are always situations when you should or even encouraged to. For example, what to do if you want to provide const interface method and use the same logic for the non-const implementation? For example, imagine tree walking logic. Should you copypaste it for writing const accessors and non-const accessors for all nodes? Or just create clean const and non-const wrappers for those tasks?