不久前,我遇到了一些代码,它们用mutable关键字标记了一个类的成员变量。据我所知,它只是允许你在const方法中修改变量:

class Foo  
{  
private:  
    mutable bool done_;  
public:  
    void doSomething() const { ...; done_ = true; }  
};

这是唯一的使用这个关键字还是有更多的它比满足眼睛?从那以后,我在一个类中使用了这种技术,将boost::mutex标记为mutable,允许const函数出于线程安全的原因锁定它,但是,说实话,这感觉有点hack。


当前回答

使用可变的一个最好的例子是,在深度复制中。在复制构造函数中,我们发送const &obj作为参数。因此,新创建的对象将是常量类型。如果我们想要改变这个新创建的const对象中的成员(大多数情况下我们不会改变,在极少数情况下我们可能会改变),我们需要将它声明为mutable。

可变存储类只能用于类的非静态非const数据成员。类的Mutable数据成员可以被修改,即使它是声明为const的对象的一部分。

class Test
{
public:
    Test(): x(1), y(1) {};
    mutable int x;
    int y;
};

int main()
{
    const Test object;
    object.x = 123;
    //object.y = 123;
    /* 
    * The above line if uncommented, will create compilation error.
    */   

    cout<< "X:"<< object.x << ", Y:" << object.y;
    return 0;
}

Output:-
X:123, Y:1

在上面的例子中,我们能够改变成员变量x的值,尽管它是声明为const的对象的一部分。这是因为变量x声明为可变的。但是如果你试图修改成员变量y的值,编译器会抛出一个错误。

其他回答

Mutable主要用于类的实现细节。类的用户不需要知道它,因此他认为“应该”是const的方法可以是。让互斥量可变的例子是一个很好的规范示例。

你对它的使用并不是一种hack,尽管像c++中的许多东西一样,mutable对于懒惰的程序员来说是一种hack,他们不想从头开始并将不应该是const的东西标记为非const。

关键字'mutable'实际上是一个保留关键字。它通常用来改变常数变量的值。如果你想要一个常量的多个值,使用关键字mutable。

//Prototype 
class tag_name{
                :
                :
                mutable var_name;
                :
                :
               };   

对于那些对用户来说是逻辑上无状态的东西(因此在公共类的api中应该有“const”getter),但在底层实现(你的.cpp中的代码)中不是无状态的东西,使用“mutable”。

The cases I use it most frequently are lazy initialization of state-less "plain old data" members. Namely, it is ideal in the narrow cases when such members are expensive to either build (processor) or carry around (memory) and many users of the object will never ask for them. In that situation you want lazy construction on the back end for performance, since 90% of the objects built will never need to build them at all, yet you still need to present the correct stateless API for public consumption.

Mutable将const的含义从按位的const更改为类的逻辑const。

这意味着具有可变成员的类将不再是按位的const,并且将不再出现在可执行文件的只读部分中。

此外,它通过允许const成员函数在不使用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.
}

请参阅其他答案了解更多细节,但我想强调的是,这不仅仅是为了类型安全,而且它会影响编译结果。