你什么时候使用C ++'mutable'关键字?

时间:2010-12-29 12:21:24

标签: c++

您何时使用C ++ mutable关键字?为什么?我认为我不必使用该关键字。我知道它用于诸如缓存(或者可能是记忆)之类的东西,但你需要在什么类和条件下使用它呢?

11 个答案:

答案 0 :(得分:43)

有时我会使用它来将互斥或其他线程同步原语标记为可变,以便通常标记为const的访问者/查询方法仍然可以锁定互斥锁。

当您需要检测代码以进行调试或测试时,它有时也很有用,因为检测通常需要从内部查询方法中修改辅助数据。

答案 1 :(得分:13)

我在内部成员计算对象缓存结果时使用了mutable:

class Transformation
{
    private:
        vec3 translation;
        vec3 scale;
        vec4 rotation;
        mutable mat4 transformation;
        mutable bool changed;
    public:
        Node()
        {
            [...]
            changed = false;
        }
        void set_translation(vec3 _translation)
        {
            translation = _translation;
            changed = true;
        }
        void set_scale(...) ...


        mat4 get_transformation() const
        {
            if(changed)
            {
                 // transformation and changed need to be mutable here
                 transformation = f(translation, scale, rotation); // This take a long time...
                 changed = false;
            }
            return transformation;
        }
};

void apply_tranformation(const Transformation* transfo)
{
    apply(transfo->get_transformation());
}

答案 2 :(得分:10)

Google code search揭示了许多用途。例如,在XTR cryptography的实现中,使用了可变成员,以便方法可以返回对结果的引用(防止生成副本)。

另一个例子,Webkit使用它来懒惰地初始化成员数据(m_lineHeight)。

答案 3 :(得分:5)

我将mutable用于按需初始化的类成员,特别是来自程序外部的数据库或源。这允许“getter”函数按需创建对象,否则它是一个常量方法。

答案 4 :(得分:4)

在模拟对象中捕获成员变量中const函数的参数值。

class Source
{
public:
    virtual ~Source() {}
    virtual std::string read(int count) const=0;
};

class SourceMock : public Source
{
public:
    mutable std::vector<int> arguments;
    std::string read(int count) const {
        arguments.push_back(count);
        return "...";
    }
};

//TEST....
SourceMock mock;
//...
VERIFY(mock.arguments.size()==2);
VERIFY(mock.arguments[0]==3);
//...

答案 5 :(得分:4)

我在锁定互斥锁时使用它来保证线程安全。互斥锁被标记为可变,因此锁定它的方法可以保持为常量。

答案 6 :(得分:2)

http://msdn.microsoft.com/en-us/library/4h2h0ktk%28v=vs.80%29.aspx将是最好的例子。嘿,我今天学到了一些东西!

答案 7 :(得分:1)

我的模板类实现了引用计数器模式。当使用 const 修饰符将其作为参数传递给函数时,无论如何都可以增加引用。因此,可以使用 const_cast 而不是mutable。

答案 8 :(得分:1)

它可以在许多情况下使用,例如

Loggerstimingaccess counters

可以在const限定的访问器中调用它们,而无需更改数据的状态。

答案 9 :(得分:0)

mutable keyword allows you to modify a variable inside a const context

e.g:

class Person {
private:
      mutable int age;

public:
    Person(int age) : age(age)  {

    }
    void setAge(int age) const {
        Person::age = age;
    }

    int getAge() const {
        return Person::age;
    }
};

int main() {

    Person person(23);
    std::cout << "Person age " << person.getAge() << std::endl;
    person.setAge(24);
    std::cout << "Person modified age " << person.getAge() << std::endl;
    return 0;
}

答案 10 :(得分:0)

如果在getter方法(通常是const)中,您需要更新存储的返回值,也可以使用它。例如,假设您有一个特定的链表实现。对于性能问题,您保留列表的最后计算长度,但是在返回列表时,如果列表已被修改,则重新计算它,否则,返回最后缓存的值。

class MyLinkedList
{
public:
  long getLength() const
  {
    if (lengthIsModified())
    {
      mLength = ...; // do the computation here
    }
    return mLength;
  }
private:
  mutable long mLength;
};

警告:由于列表中有某些特定操作(例如合并),因此始终保持最新状态并不容易。