1
votes

I am studying C++ and I read that: If a data member is declared mutable, then it is legal to assign a value to this data member from a const member function. But the following code compiled without any error or warning by gcc. (It is not a real-world code example, I just wrote it to test the mutable keyword)

class M
{
public:
  M(){x=10;};
  int getX() {x++; return x;};
private:
  mutable int x;
};

int main()
{
  M xx;
  std::cout << xx.getX() << std::endl;
}

Shouldn't I declare getX as const?

Edit 1 (ForEver's answer makes the things more clear), the following code will not be compiled:

class M
{
public:
  M(){x=10;};
  int getX() const {x++; return x;};
private:
  int x;
};

int main()
{
  M xx;
  std::cout << xx.getX() << std::endl;
}
3
That statement doesn't say that the member function must be const. I recommend learning and understanding const before learning mutable.Drew Dormann
Usually anything, that is allowed in const function is also allowed in non-const function. Const function is more restrictive than non-const one.Spook
I mean no offense by this, but how would you rate your English comprehension? The problem here seems to be that you have a basic misunderstanding of the meaning of that sentence.Benjamin Lindley
You are true, my English comprehension was the problem but was it to bad to ask? Anyway.Avraam Mavridis
No, no problem with asking. I was just curious.Benjamin Lindley

3 Answers

3
votes

It's legal to modify mutables in const functions and of course it's legal to modify mutables in non-const functions (as each non-const member-variable). mutable keyword allows modify variable in const functions, but doesn't give any restrictions on modifying in non-const functions.

0
votes

mutable is typically used to allow const qualified member functions to modify cached data. You can declare getX() as const and happily modify x, that's what mutable is for. However it's generally considered a bad idea to modify the internal state of an object in a member function that by it's declaration says it doesn't.

For example, you have a const member function that calculates a value based on the contents of a container. If the container has a lot of elements it might take a long time to get the result. If the result only changes when you add or remove elements from the container you could cache it for later use. Since the member function is const qualified you would need to declare the result variable as mutable. Since the result can be calculated from the existing data in the container the cached value isn't considered part of the internal state of the object and it's considered OK to modify it since of a const function.

int Foo::CalcResult() const
{
    if(hasValidCache_ == false)
    {

        // ... recalc value ...

        // Cache the result
        hasValidCache = true;
        cachedValue_ result;
    }

    return cachedValue_;
}
0
votes

The statement means this.

class M
{
public:
   M(){x=10;};
   int getX() const
 //           ^^^^^ If a member function is const...

                   {x++; return x;};
 //                 ^^^ ...and it modifies a member variable...
private:
   mutable int x;
// ^^^^^^^ ...then that variable must be mutable.
};