简体   繁体   中英

Mutable variable changed by a non-const member function

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;
}

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.

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_;
}

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.
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM