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 changes the meaning of
const
from bitwise const to logical const for the class.This means that classes with mutable members are longer be bitwise const and will no longer appear in read-only sections of the executable.
Furthermore, it modifies type-checking by allowing
const
member functions to change mutable members without usingconst_cast
.See the other answers for more details but I wanted to highlight that it isn't merely for type-saftey and that it affects the compiled result.
The mutable can be handy when you are overriding a const virtual function and want to modify your child class member variable in that function. In most of the cases you would not want to alter the interface of the base class, so you have to use mutable member variable of your own.
The very keyword 'mutable' is actually a reserved keyword.often it is used to vary the value of constant variable.If you want to have multiple values of a constsnt,use the keyword mutable.
Mutable is used when you have a variable inside the class that is only used within that class to signal things like for example a mutex or a lock. This variable does not change the behaviour of the class, but is necessary in order to implement thread safety of the class itself. Thus if without "mutable", you would not be able to have "const" functions because this variable will need to be changed in all functions that are available to the outside world. Therefore, mutable was introduced in order to make a member variable writable even by a const function.
The classic example (as mentioned in other answers) and the only situation I have seen the
mutable
keyword used in so far, is for caching the result of a complicatedGet
method, where the cache is implemented as a data member of the class and not as a static variable in the method (for reasons of sharing between several functions or plain cleanliness).In general, the alternatives to using the
mutable
keyword are usually a static variable in the method or theconst_cast
trick.Another detailed explanation is in here.
The
mutable
keyword is a way to pierce theconst
veil you drape over your objects. If you have a const reference or pointer to an object, you cannot modify that object in any way except when and how it is markedmutable
.With your
const
reference or pointer you are constrained to:const
.The
mutable
exception makes it so you can now write or set data members that are markedmutable
. That's the only externally visible difference.Internally those
const
methods that are visible to you can also write to data members that are markedmutable
. Essentially the const veil is pierced comprehensively. It is completely up to the API designer to ensure thatmutable
doesn't destroy theconst
concept and is only used in useful special cases. Themutable
keyword helps because it clearly marks data members that are subject to these special cases.In practice you can use
const
obsessively throughout your codebase (you essentially want to "infect" your codebase with theconst
"disease"). In this world pointers and references areconst
with very few exceptions, yielding code that is easier to reason about and understand. For a interesting digression look up "referential transparency".Without the
mutable
keyword you will eventually be forced to useconst_cast
to handle the various useful special cases it allows (caching, ref counting, debug data, etc.). Unfortunatelyconst_cast
is significantly more destructive thanmutable
because it forces the API client to destroy theconst
protection of the objects (s)he is using. Additionally it causes widespreadconst
destruction:const_cast
ing a const pointer or reference allows unfettered write and method calling access to visible members. In contrastmutable
requires the API designer to exercise fine grained control over theconst
exceptions, and usually these exceptions are hidden inconst
methods operating on private data.(N.B. I refer to to data and method visibility a few times. I'm talking about members marked as public vs. private or protected which is a totally different type of object protection discussed here.)