【C/C++】一步一步玩转mutable

C++ 关键字 mutable 主要用于打破 const 限制,允许你在某些被标记为 const 的上下文中仍然修改成员变量。


基础语法

class Example {
    mutable int counter = 0;
public:
    void inspect() const {
        ++counter; // 合法:counter 是 mutable
    }
};

使用场景与解释

1. 在 const 成员函数中修改成员变量

场景描述:

你希望在 const 成员函数中维护某些统计或缓存变量(如调用计数、缓存标志等),但不破坏 const 接口语义。

示例:
class Cache {
    mutable bool isValid = false;
    mutable int cachedValue = 0;

public:
    int compute() const {
        if (!isValid) {
            cachedValue = 42; // expensive computation
            isValid = true;
        }
        return cachedValue;
    }
};

2. 线程同步中的状态变量

场景描述:

在并发程序中,对象是 const 的,但仍需允许 mutable 成员用于同步(如 std::mutex, 原子变量)。

示例:
#include 

class ThreadSafe {
    mutable std::mutex mtx;

public:
    void doWork() const {
        std::lock_guard<std::mutex> lock(mtx);
        // 安全地修改共享状态
    }
};

3. 懒加载(Lazy Initialization)缓存机制

场景描述:

const 方法中进行惰性初始化缓存(如懒加载文件内容、哈希值等)。

示例:
class File {
    std::string filename;
    mutable std::string content;
    mutable bool loaded = false;

public:
    std::string getContent() const {
        if (!loaded) {
            // 加载文件
            content = "file content ...";
            loaded = true;
        }
        return content;
    }
};

4. 模拟逻辑 const:对外不可变,对内可变

场景描述:

对外提供 const 接口,但内部实现需要缓存/统计,仍保持语义上“不可变”。

示例:
class Logger {
    mutable int logCount = 0;

public:
    void log(const std::string& msg) const {
        ++logCount;
        std::cout << msg << "\n";
    }
};

5. 用于重载与 STL 接口的 operator<operator== 等场景下的缓存比较结果

场景描述:

在重载比较运算符中缓存比较结果提升性能,但必须是 const 方法。

示例:
class LargeObject {
    std::vector<int> data;
    mutable bool cached = false;
    mutable size_t hash = 0;

public:
    bool operator==(const LargeObject& other) const {
        return getHash() == other.getHash();
    }

    size_t getHash() const {
        if (!cached) {
            hash = std::hash<std::string>{}("simulate expensive hash");
            cached = true;
        }
        return hash;
    }
};

6. 模拟引用计数、访问计数等非逻辑状态数据

场景描述:

shared_ptr 自定义实现中引用计数可用 mutable

示例:
class RefCounted {
    mutable int refCount = 0;

public:
    void addRef() const {
        ++refCount;
    }

    int getRefCount() const {
        return refCount;
    }
};

mutable 不适用的场景

场景 原因
修改 const 变量 mutable 不能用于普通变量,必须是类的非静态成员变量
静态成员变量 mutable 不适用于 static 成员
函数参数 mutable 不能修饰普通函数参数
普通局部变量 无意义,局部变量默认可变

总结:mutable 的核心价值

关键作用 场景
打破 const 限制 用于 const 成员函数中修改成员
支持懒加载和缓存优化 Caching、Hash、懒加载资源
保持语义 const,避免 API 不一致 外部保持不变性,内部允许优化
支持线程安全成员 mutex, atomic 等同步对象

你可能感兴趣的:(C/C++,c语言,c++,开发语言)