C++学习笔记-mutable

mutable关键字允许在const成员函数中修改被标记为mutable的成员变量。这在某些特殊情况下非常有用,比如需要在const函数中进行调试计数或缓存操作。

mutable的基本用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class Entity
{
private:
    std::string m_Name;
    mutable int m_DebugCount = 0;  // 使用mutable标记
public:
    // 这是一个const成员函数,但我们想要记录一下这个函数被调用了多少次,这时候就需要用到mutable
    const std::string& GetName() const
    {
        m_DebugCount++;  // 在const函数中修改mutable成员变量
        return m_Name;
    }
    
    int GetDebugCount() const 
    {
        return m_DebugCount;
    }
};

使用示例:

1
2
3
4
5
6
7
int main()
{
    const Entity e;
    e.GetName();  // 调用const函数,但内部的mutable变量可以被修改
    
    std::cout << e.GetDebugCount() << std::endl;  // 输出调用次数
}

mutable的应用场景

1. 调试计数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Logger
{
private:
    mutable int m_CallCount = 0;
public:
    void Log(const std::string& message) const
    {
        m_CallCount++;  // 记录调用次数
        std::cout << "[" << m_CallCount << "] " << message << std::endl;
    }
};

2. 缓存机制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class ExpensiveCalculation
{
private:
    mutable bool m_Cached = false;
    mutable double m_CachedResult = 0.0;
public:
    double Calculate() const
    {
        if (!m_Cached)
        {
            // 执行复杂计算
            m_CachedResult = 3.14159 * 2.71828;  // 示例计算
            m_Cached = true;
        }
        return m_CachedResult;
    }
};

注意事项

  1. 谨慎使用:mutable应该只用于不影响对象逻辑状态的成员变量
  2. 语义一致性:即使变量是mutable的,const函数的语义仍应保持不变
  3. 线程安全:在多线程环境中,mutable成员变量可能需要额外的同步机制

总结

  1. 将成员变量标记为mutable,意味着即使在const成员函数中也可以修改该成员变量
  2. mutable主要使用场景包括调试计数、缓存机制等不影响对象逻辑状态的操作
  3. mutable还有一个使用场景是在lambda中,但这属于更高级的用法,大部分情况下不需要
updatedupdated2025-09-202025-09-20