- 先回顾前提:const 成员函数的 “限制”
之前我们讲过,函数后的 const 会让编译器强制保证:这个成员函数里不能修改类的任何成员变量。
但实际开发中,有些变量的修改并不会改变对象的 “核心逻辑状态”(比如统计函数被调用了多少次、缓存临时数据、加锁解锁),如果因为这些辅助变量的修改就不能加 const,会让代码变得不灵活 ——mutable 就是为解决这个问题而生的。
- mutable 的核心作用:给 const 函数 “开绿灯”
mutable 关键字的核心定义:
修饰类的非静态成员变量,让它不受 const 成员函数的限制 —— 即使在 const 函数里,也能修改这个变量。
通俗理解
把类的成员变量分成两类:
核心数据:比如点的数量 num_points_、索引指针 point_index_—— 这些变量的修改会改变对象的 “逻辑状态”,必须受 const 函数限制;
辅助数据:比如函数调用次数 call_count_、缓存数据 cache_val_、锁 mutex_—— 这些变量的修改不影响对象的核心逻辑,mutable 就是给这类变量 “开绿灯”,允许在 const 函数里修改。
- 新手友好的完整例子(对比理解)
我们写两个版本的代码,先看不加 mutable 的报错情况,再看加 mutable 的正确用法:
版本 1:不加 mutable → 编译报错
点击查看代码
#include <iostream>
using namespace std;
class PointManager {
public:
PointManager(int val) : core_val_(val), call_count_(0) {}
// const 成员函数:读取核心数据
int get_val() const {
// 想统计这个函数被调用了多少次 → 尝试修改 call_count_
call_count_++; // ❌ 编译报错!const 函数不能修改普通成员变量
return core_val_;
}
private:
int core_val_; // 核心数据:点的数值
int call_count_; // 辅助数据:函数调用次数
};
int main() {
const PointManager pm(100);
cout << pm.get_val() << endl;
return 0;
}
版本 2:加 mutable → 正常运行
只需要给 call_count_ 加 mutable 修饰,就能在 const 函数里修改它:
点击查看代码
#include<iostream>
using namespace std;
class PointManager {
public:
PointManager(int val):core_val_(val),call_count_(0){}
//const 成员函数:读取核心数据
int get_val() const {
//想统计这个函数被调用了多少次->尝试修改call_count_
call_count_++;//编译报错!const函数不能修改普通成员变量
cout << "get_val()已被调用 " << call_count_ << " 次" << endl;
return core_val_;
}
private:
int core_val_;//核心数据:点的数值
mutable int call_count_;//辅助函数:函数调用次数
};
int main() {
const PointManager pm(100);
cout << "核心值"<<pm.get_val() << endl;
cout << "核心值" << pm.get_val() << endl;
return 0;
}
运行结果:
![image]()