Consider the following (example) code:
class A
{
private:
int *_a;
public:
A() { /* initialize _a to something */ }
~A() { /* deallocate _a */ }
void setA(int i) const
{
_a[i] = 3;
}
};
This code compiles and will perform as expected (i.e., if you call setA
with some input i
, it will set the i
th element of _a
to 3
). My concern is with the const
modifier attached to the function setA
. There is no danger of a compiler error (or worse, undefined behavior) due to this modifier – the class A
only contains a pointer to the data that is being modified, not the data itself. With that said, I can't help but feel that using the const
modifier for a function that does in fact modify the data that A
is in charge of maintaining is wrong, somehow. Am I being oversensitive here, or is this truly bad practice?
Best Answer
In your example it is probably very bad idea to modify
_a[i]
.Having said that I would like to elaborate a bit more:
const
is a very useful keyword. If you read some Bjarne's or Scott's books, there is written to use const as often as possible. Moreover changing data in function declaredconst
is not only possible, it is sometimes good practice! Just remember that care is needed when deciding if your case is one of those 'some' times. Why on Earth they would put keywordmutable
in C++ if it should not be used?An example (from one of aforementioned authors if I remember correctly) of good usage of
mutable
:Consider class Polygon:
It is quite straightforaward, isn't it? We don't want to calculate area every time we are asked to return it, so we store its value in
m_area
member variable and return this variable. Methoddouble area()
isconst
, it doesn't change anything after all. The thing is we have to compute area every time we change our Polygon! Let's say we add a hundred vertexes one by one... A hundred area recalculations! 99 of those totally unnecessary. We want to recalculate only if we are asked to deliver area. So what do we do?We use
mutable
!The effect is pretty nice: for a user of our class method
double area()
still doesn't modify object it's working on, so it is stillconst
. But inside we gained a lot! Area will be recalculated only when there is need for it. If nobody asks for area it won't be calculated at all!So, as I understand it,
const
should indicate that "as far as class user is concerned" method does not modify object. User of our API is usually not interested in implementation details. If he is, then we have documentation :) .But beware: using
mutable
because "it's few lines of code less" or something like that is a huge mistake. If you make your methodconst
then keep your word and usemutable
with utmost care only! Otherwise you, and users of your code soon will be in big trouble.