A while ago I came across some code that marked a member variable of a class with the mutable
keyword. As far as I can see it simply allows you to modify a variable in a const
method:
class Foo
{
private:
mutable bool done_;
public:
void doSomething() const { ...; done_ = true; }
};
Is this the only use of this keyword or is there more to it than meets the eye? I have since used this technique in a class, marking a boost::mutex
as mutable allowing const
functions to lock it for thread-safety reasons, but, to be honest, it feels like a bit of a hack.
Mutable is for marking specific attribute as modifiable from within
const
methods. That is its only purpose. Think carefully before using it, because your code will probably be cleaner and more readable if you change the design rather than usemutable
.http://www.highprogrammer.com/alan/rants/mutable.html
Examples the author gives include caching and temporary debugging variables.
It's useful in situations where you have hidden internal state such as a cache. For example:
And then you can have a
const HashTable
object still use itslookup()
method, which modifies the internal cache.Well, yeah, that's what it does. I use it for members that are modified by methods that do not logically change the state of a class - for instance, to speed up lookups by implementing a cache:
Now, you must use this with care - concurrency issues are a big concern, as a caller might assume that they are thread safe if only using
const
methods. And of course, modifyingmutable
data shouldn't change the behavior of the object in any significant fashion, something that could be violated by the example i gave if, for instance, it was expected that changes written to disk would be immediately visible to the app.Your use of it isn't a hack, though like many things in C++, mutable can be hack for a lazy programmer who doesn't want to go all the way back and mark something that shouldn't be const as non-const.
Your use with boost::mutex is exactly what this keyword is intended for. Another use is for internal result caching to speed access.
Basically, 'mutable' applies to any class attribute that does not affect the externally visible state of the object.
In the sample code in your question, mutable might be inappropriate if the value of done_ affects external state, it depends on what is in the ...; part.
One of the best example where we use mutable is, in deep copy. in copy constructor we send
const &obj
as argument. So the new object created will be of constant type. If we want to change (mostly we won't change, in rare case we may change) the members in this newly created const object we need to declare it asmutable
.mutable
storage class can be used only on non static non const data member of a class. Mutable data member of a class can be modified even if it's part of an object which is declared as const.In the above example, we are able to change the value of member variable
x
though it's part of an object which is declared as const. This is because the variablex
is declared as mutable. But if you try to modify the value of member variabley
, compiler will throw an error.