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 declared const
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 keyword mutable
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:
class Polygon
{
void calculate_area() { /* we calculate m_area */ }
std::vector<Vertex> m_vertexes;
double m_area;
public:
Polygon(std::initializer_list<Vertex> v_list): m_vertexes(v_list) {}
double area() const { return m_area; }
void add_vertex(Vertex v)
{
m_vertexes.push_back(v);
calculate_area();
}
};
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. Method double area()
is const
, 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
!
class Polygon
{
void calculate_area() const
{
/* we calculate m_area */
m_recalculate_area = false;
}
std::vector<Vertex> m_vertexes;
mutable bool m_recalculate_area = false;
mutable double m_area = 0.0;
public:
Polygon(std::initializer_list<Vertex> v_list): m_vertexes(v_list)
{ m_recalculate_area = true; }
double area() const
{
if(m_recalculate_area)
{ calculate_area(); }
return m_area;
}
void add_vertex(Vertex v)
{
m_vertexes.push_back(v);
m_recalculate_area = true;
}
};
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 still const
. 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 method const
then keep your word and use mutable
with utmost care only! Otherwise you, and users of your code soon will be in big trouble.
void
, then it has to modify state to have any observable effect._a
), just what it points to. This will have an observable effect on the data, but not on the member variable (which is just the pointer).const
int &
(viareturn _a[i];
). This still leaves open the possibility of mutation, the signature still indicatesconst
, and it isn't immediately obvious anymore. (Let me know if you think I should edit this addition into the question as well)const
(from what I understand of it) is just not a very useful feature.