一、mutable作用
- mutable的设计目的,是为了允许类成员变量在const成员成函数中被修改
二、mutable修饰的成员变量破坏了const成员函数的限制规则
const修饰的成员函数规则:
-
不允许修改任何非静态成成员变量
-
不允许调用其他非const成员函数
但mutable关键字破坏了第一个规则
- 代码
cpp
class MyClass {
private:
int age; // 普通变量
mutable int cache; // mutable变量
public:
void setAge(int a) const {
// age = a; // ❌ 编译报错!const函数中不能修改普通成员
cache = a; // ✅ OK!mutable变量可以在const函数中修改
}
};
三、mutable使用场景
1、惰性缓存
-
使用const函数返回对象数据
-
但是这个函数希望第一次读取时计算数据并进行缓存结果,后续直接返回缓存值
-
则mutable修饰的成员变量,可满足上面的要求
-
代码
cpp
class DataProcessor {
private:
std::string raw_data;
mutable bool cache_valid; // 缓存是否有效(需在const中修改)
mutable int cached_result; // 缓存的结果(需在const中修改)
public:
int getResult() const { // 逻辑上是只读函数,标记为const
if (!cache_valid) {
// 执行昂贵计算(如遍历大数据)...
cached_result = raw_data.size() * 10;
cache_valid = true; // ✅ 因为是mutable,所以可以在const函数中修改
}
return cached_result;
}
};
2、使用mutable修饰的互斥锁对象,实现线程安全的const函数
-
将互斥锁Mutex声明为mutable,让const函数能安全地加锁
-
代码
cpp
#include <mutex>
class ThreadSafeCounter {
private:
mutable std::mutex mtx; // 锁必须是mutable,因为const函数中需要上锁
int value = 0;
public:
int get() const { // 获取值,逻辑上只读
std::lock_guard<std::mutex> lock(mtx); // ✅ 调用 mtx.lock() 改变锁状态
return value;
}
};