C++中mutable关键字
参考链接:https://www.zhihu.com/question/64969053
这个关键字的允许你将一个类中的变量声明为易变的,从而const对象也能修改它。它就不算作类的状态的了。
我感觉这个东西可以用在性能优化和多线程的锁。
例如计算平均值:
有一个类统计了很多数值,传给很多人,很多人去拿平均值。但是平均值不是加完值直接算出来的,而是访问平均值的时候再算。这样就可以避免不必要的计算,访问的时候又可能会访问很多次,但是只想算一次,所以肯定要用一个变量表示现在算了没算,最简单的就是用cnt来表示,既能表示现在加了几个值了,又能表示现在算没算平均值。
mutable计算平均值代码:
#include <iostream>
#include <string>
using namespace std;
class CalcAverage {
public:
CalcAverage() : average(0), cnt(0) {};
const double getAverage() const {
if(cnt>1) {
// 如果average不是mutable,这里就会报错,因为函数体声明了为const,但是这里却修改了类中的变量。
average /= cnt;
cnt = 1;
}
return average;
};
void addValue(double t) {
average += t;
cnt++;
}
private:
// double average;
mutable double average;
mutable int cnt;
};
void show(const CalcAverage& calc) {
cout<<calc.getAverage()<<endl;
}
int main() {
CalcAverage calc;
for (int i=0;i!=5;++i) {
calc.addValue(i);
}
show(calc);
show(calc);
show(calc);
return 0;
}
在多线程加锁的时候也需要将锁设为mutable,这样const对象就也可以加锁访问数据了。
作者:Timothy Liu
链接:https://www.zhihu.com/question/64969053/answer/1809304604
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#pragma once
#ifndef CONCURRENCY_CONCURRENT_QUEUE_HPP
#define CONCURRENCY_CONCURRENT_QUEUE_HPP
#include <queue>
#include <mutex>
#include <utility>
#define CONCURRENT_NAMESPACE_BEGIN namespace concurrency {
#define CONCURRENT_NAMESPACE_END }
CONCURRENT_NAMESPACE_BEGIN
template <typename Elem>
class concurrent_queue
{
public:
void clear()
{
std::lock_guard<std::mutex> lg(mtx);
while (!q.empty()) q.pop();
}
[[nodiscard]] bool empty() const
{
std::lock_guard<std::mutex> lg(mtx);
bool ret = q.empty();
return ret;
}
template <typename... Ts>
void push(Ts&&... args)
{
std::lock_guard<std::mutex> lg(mtx);
q.emplace(std::forward<Ts>(args)...);
}
bool try_pop(Elem& out)
{
std::lock_guard<std::mutex> lg(mtx);
if (q.empty()) return false;
out = std::move(q.front());
q.pop();
return true;
}
private:
std::queue<Elem> q;
mutable std::mutex mtx;
};
CONCURRENT_NAMESPACE_END
#undef CONCURRENT_NAMESPACE_END
#undef CONCURRENT_NAMESPACE_BEGIN
#endif //!CONCURRENCY_CONCURRENT_QUEUE_HPP