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

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

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


当前回答

mutmutable确实存在,因为你可以推断允许在一个常量函数中修改数据。

这样做的目的是,您可能有一个函数对对象的内部状态“什么都不做”,因此您将函数标记为const,但您可能确实需要以不影响其正确功能的方式修改一些对象的状态。

关键字可以作为对编译器的提示——理论上的编译器可以将一个常量对象(例如全局变量)放在内存中,并将其标记为只读。可变的存在提示不应该这样做。

下面是声明和使用可变数据的一些有效理由:

线程安全。声明一个可变的boost::mutex是完全合理的。 统计数据。给定函数的部分或全部实参,计算函数的调用次数。 记忆。计算一些代价高昂的答案,然后将其存储起来以备将来参考,而不是重新计算。

其他回答

Mutable用于在const方法中将特定属性标记为可修改的。这是它唯一的目的。在使用它之前要仔细考虑,因为如果你改变设计而不是使用mutable,你的代码可能会更清晰,更易读。

http://www.highprogrammer.com/alan/rants/mutable.html

所以如果上面的疯狂不是什么 可变是用来干什么的?这是 微妙的情况是:mutable是用于 对象在逻辑上的情况 不变,但在实践中需要 改变。这样的案例少而又远 两者之间,但它们确实存在。

作者给出的例子包括缓存和临时调试变量。

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

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

使用可变的一个最好的例子是,在深度复制中。在复制构造函数中,我们发送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的值,编译器会抛出一个错误。

它在有隐藏内部状态(如缓存)的情况下非常有用。例如:

class HashTable
{
...
public:
    string lookup(string key) const
    {
        if(key == lastKey)
            return lastValue;

        string value = lookupInternal(key);

        lastKey = key;
        lastValue = value;

        return value;
    }

private:
    mutable string lastKey, lastValue;
};

然后可以让一个const HashTable对象仍然使用它的lookup()方法,该方法修改内部缓存。