今天我发现自己编写了一些类似下面的代码,我想知道这是否是对mutable
关键字的有效使用。
我的想法是想通过const
指针访问某些属性,但我只想在需要时评估这些属性。
class Person {
public:
Person() : age(-1) {}
~Person() {}
int GetAge() const {
if( age == -1 ) { CalculateAge(); }
return age;
}
private:
mutable int age;
// Note: as a result of being called from a `const` method,
// CalculateAge has to be const itself.
void CalculateAge() const {
age = 33; // do calculation based on date of birth or whatever.
}
};
这是mutable
的要点,还是我在这里滥用它?
我用自己的理由说服了上面的代码等同于
class Person {
public:
Person() {}
~Person() {}
int GetAge() const {
// Always do the expensive calculation here
return 33;
}
};
或
class Person {
public:
Person() {
// Do the expensive calculation here even if age is never used.
age = 33;
}
~Person() {}
int GetAge() const {
return age;
}
private:
int age; // non-mutable
};
其中GetAge()
被正确标记为const
;它是否实际缓存结果是一个与我的类客户端无关的实现细节。
编辑:此外,我还有兴趣听取任何其他不涉及使所有内容变为非{...}}的解决方案。
答案 0 :(得分:1)
不是一个完整的答案,但是,它看起来像是虐待我。您应该仅将 mutable
标记为不修改对象外部状态的成员。在您的情况下,您有一个方法GetAge
,它公开了成员age
,这意味着更改age
会更改对象的“可见”状态。
修改强>
编辑后,我不得不说它没问题。只要您使用age
之类的成员cache
。
答案 1 :(得分:1)
mutable,因为它不会更改对象的外部状态,但您仍需要更改某个内部状态。在我看来,这正是你在这里所拥有的。延迟计算年龄只是一些内部优化,从用户隐藏优化是合理的。用户将不理解为什么让年龄修改对象(“外部状态”)。
但是:我不喜欢可变的。如果你有一个驻留在只读内存中的const对象(例如只读文件映射),mutable可能会成为一个问题。如果然后在该对象上调用const方法,编译器将不会抱怨。但是如果你修改了一些可变对象,代码就会崩溃。