Does the 'mutable' keyword have any purpos

2019-01-01 01:42发布

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.

18条回答
明月照影归
2楼-- · 2019-01-01 01:44

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 using const_cast.

class Logical {
    mutable int var;

public:
    Logical(): var(0) {}
    void set(int x) const { var = x; }
};

class Bitwise {
    int var;

public:
    Bitwise(): var(0) {}
    void set(int x) const {
        const_cast<Bitwise*>(this)->var = x;
    }
};

const Logical logical; // Not put in read-only.
const Bitwise bitwise; // Likely put in read-only.

int main(void)
{
    logical.set(5); // Well defined.
    bitwise.set(5); // Undefined.
}

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.

查看更多
时光乱了年华
3楼-- · 2019-01-01 01:46

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.

查看更多
宁负流年不负卿
4楼-- · 2019-01-01 01:46

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.

//Prototype 
class tag_name{
                :
                :
                mutable var_name;
                :
                :
               };   
查看更多
人间绝色
5楼-- · 2019-01-01 01:51

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 mutable specified informs both the compiler and the reader that it is safe and expected that a member variable may be modified within a const member function.

查看更多
流年柔荑漫光年
6楼-- · 2019-01-01 01:51

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 complicated Get 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 the const_cast trick.

Another detailed explanation is in here.

查看更多
泪湿衣
7楼-- · 2019-01-01 01:53

The mutable keyword is a way to pierce the const 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 marked mutable.

With your const reference or pointer you are constrained to:

  • only read access for any visible data members
  • permission to call only methods that are marked as const.

The mutable exception makes it so you can now write or set data members that are marked mutable. That's the only externally visible difference.

Internally those const methods that are visible to you can also write to data members that are marked mutable. Essentially the const veil is pierced comprehensively. It is completely up to the API designer to ensure that mutable doesn't destroy the const concept and is only used in useful special cases. The mutable 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 the const "disease"). In this world pointers and references are const 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 use const_cast to handle the various useful special cases it allows (caching, ref counting, debug data, etc.). Unfortunately const_cast is significantly more destructive than mutable because it forces the API client to destroy the const protection of the objects (s)he is using. Additionally it causes widespread const destruction: const_casting a const pointer or reference allows unfettered write and method calling access to visible members. In contrast mutable requires the API designer to exercise fine grained control over the const exceptions, and usually these exceptions are hidden in const 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.)

查看更多
登录 后发表回答