您何时使用C ++ mutable
关键字?为什么?我认为我不必使用该关键字。我知道它用于诸如缓存(或者可能是记忆)之类的东西,但你需要在什么类和条件下使用它呢?
答案 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)
它可以在许多情况下使用,例如
Loggers
,timing
,access 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;
};
警告:由于列表中有某些特定操作(例如合并),因此始终保持最新状态并不容易。