首页 > 编程笔记 > C++笔记 阅读:18

C++ mutable的用法(附带实例)

关键字 mutable 并不是在 C++11 中新引入的关键字,但是很少有 C++ 相关的资料中提及这个关键字。

mutable 用于修饰类的非静态成员变量。它的作用是允许在一个被声明为 const 的成员函数内修改被修饰的成员变量的值。

在默认情况下,const 成员函数不允许修改类的成员变量,然而,有时可能希望在某些特殊情况下仍然能够修改这些变量,此时就可以使用 mutable 关键字声明一个成员变量,使它可以在 const 成员函数内部被修改。

下面是一个示例代码:
#include <iostream>
class MyClass
{
public:
    void setValue(int value) const
    {
        mutableValue = value;          //修改被 mutable 修饰的变量
    }
    int getValue() const
    {
        return mutableValue;
    }
private:
    mutable int mutableValue;         //声明为 mutable 的成员变量
};

int main()
{
    MyClass a;
    a.setValue(10);
    std::cout << a.getValue() << std::endl;
    return 0;
}
运行结果为:

10

在上面的例子中,setValue() 函数被声明为 const,但是它依然可以修改 mutableValue,而 getValue() 函数也被声明为 const,因此在该函数内不允许修改成员变量。

需要注意的是,mutable 破坏了 const 的约束,要谨慎使用 mutable,确保它在合适的场景下使用。例如,在多线程操作时需要对数据进行加锁处理,但同时接口函数需要使用 const 修饰,在这种情况下对线程锁使用 mutable 修饰是非常有用的,代码如下:
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>

class MyClass
{
public:
    void caculate(int value)
    {
        //修改 m_mutex 的状态
        std::unique_lock<std::mutex> lock(m_mutex);
        for(int i = 0; i < value; i++) {
            m_value = i;
        }
    }

    int getValue() const
    {
        //因为 getValue 使用了 const 约束,如果 m_mutex 没有使用 mutable 修饰
        //修改 m_mutex 的状态操作则无法进行
        std::unique_lock<std::mutex> lock(m_mutex);
        return m_value;
    }

private:
    int m_value;
    mutable std::mutex  m_mutex;      //声明为 mutable 的成员变量
};

int main()
{
    MyClass a;
    //使用 lambda 启动一个线程
    std::thread thda([&]() { a.caculate(10000); });
    std::thread thdb([&]() { a.caculate(20000); });

    thda.detach();
    thdb.detach();

    //等候线程运行结束,这里需要注意,使用这种方法在不同的硬件或者系统中运行情况会不一致
    std::this_thread::sleep_for(std::chrono::seconds(1));

    std::cout << a.getValue() << std::endl;
    return 0;
}

相关文章