正如我在这个问题中所介绍的那样,
C++11's "const==mutable", Provide two classes for efficiency?
,
在C++98或线程之前,尽管在某些情况下是不正确的,但使用mutable编写内部隐藏的类是很常见的。
在C++11中,Herb Sutter说从现在开始
const == thread safe
,这意味着可变字段应该由互斥体保护。
所以我认为,一些真正知道他/她在做什么的人实际上可以通过在非const的情况下做一些特殊的事情来获得单个类的更通用的版本。
struct Widget {
private:
int getValue_aux() const{
if (cacheValid) return cachedValue;
else {
cachedValue = expensiveQuery(); // write data mem
cacheValid = true; // write data mem
return cachedValue;
}
}
public:
int getValue() {
return get_value_aux(); // no lock
}
int getValue() const{
std::lock_guard<std::mutex> guard{m}; // lock mutex
get_value_aux();
} // unlock mutex
...
private:
mutable std::mutex m;
mutable int cachedValue;
mutable bool cacheValid;
...
};
因此,a)普通用户可以使用非const实例
Widget
到
作记号
它不打算在线程安全上下文中使用,也不需要为互斥锁付费b)真正知道自己在做什么的用户可以
const_cast
或者把它包起来
mutable
如果他知道线程安全在代码的特定点上不会成为问题(但他/她仍在存储互斥体)。
这是对Widget的合理概括吗?还是有缺陷?
注:如果你认为
const
和非-
const
为了提高效率,应该提供版本,您可能会发现这个问题也很有趣:
C++11's "const==mutable", How to implement copy? efficiently?