欢迎光临
我们一直在努力

小学生学C++编程语法知识(C++中的 mutable 详解)


C++中的 mutable 详解

——为什么“不能改变”的东西,有时候可以改变?

同学们,我们前面学习了 const:

const 表示“不允许修改”。


比如:

const int x = 10;

x = 20; // 错误!


因为:

x 是常量
不能改变

那么问题来了:

如果一个东西整体不能改变,但是里面有一个小地方希望可以偷偷变化,怎么办?

这时候 C++ 给我们提供了一个特殊工具:

mutable(可变的)


一、先回忆 const 成员函数

在讲 mutable 之前,我们先复习一下:

类里面的 const 函数

例如:

class Student
{
public:

int age;

void show() const
{
cout << age;
}
};

注意:

void show() const

后面的 const

表示:

这个函数保证不会修改对象的数据。


例如:

class Student
{
public:

int age;

void change() const
{
age = 10; // 错误
}

};


为什么?

因为:

const函数

不能修改成员变量


二、生活中的例子理解 mutable

假设:

你有一本:

《我的个人档案》

里面有:

姓名
年龄
生日
访问次数


例如:

class Book
{
public:

string name;

int price;

int visit;

};


现在有一个函数:

查看书的信息:

void show() const
{
cout << name;
}

我们希望:

用户每看一次书:

visit + 1

表示:

这本书被查看了多少次


于是:

void show() const
{
visit++;

cout << name;
}


编译器会说:

错误!

因为:

show() 是 const函数

不能修改任何成员变量


怎么办?

难道访问次数不能增加?

当然不是。

因为:

访问次数这个数据:

不是书本本身的信息。


书本:

名字
价格
作者

这些不能变。


但是:

访问次数

只是一个记录信息。


所以:

我们希望:

普通数据:
不能改

特殊数据:
允许改

这就是:

mutable 出场!


三、mutable的作用

一句话:

mutable 修饰的成员变量,可以在 const 成员函数中被修改。


格式:

mutable 数据类型 变量名;


例如:

class Book
{
public:

string name;

int price;

mutable int visit;

void show() const
{
visit++;

cout << name;
}

};

现在:

show()

里面:

visit++;

合法!


四、完整例子

#include<iostream>
using namespace std;

class Book
{

private:

string name;

int price;

mutable int count;

public:

Book(string n,int p)
{
name=n;
price=p;
count=0;
}

void show() const
{
count++;

cout<<"书名:"<<name<<endl;

cout<<"价格:"<<price<<endl;

cout<<"查看次数:"<<count<<endl;
}

};

int main()
{

Book b("C++入门",50);

b.show();

b.show();

b.show();

return 0;
}

输出:

书名:C++入门
价格:50
查看次数:1

书名:C++入门
价格:50
查看次数:2

书名:C++入门
价格:50
查看次数:3


五、为什么C++允许这样设计?

我们思考:

const的本质是什么?


const告诉别人:

我承诺,不修改这个对象的重要内容。


但是:

有一些变量:

虽然会变化,

但是:

它不是对象真正的数据。

例如:


例1:访问次数

网站:

用户名
密码
等级

访问次数

访问次数变化:

但是用户名没有变化。


例2:缓存数据

比如:

计算:

1+2+3+…+100000

很慢。

第一次:

计算:

结果=5000050000

保存起来。

第二次:

直接返回。

这个保存结果:

叫:

缓存(cache)

缓存可以改变:

但是:

对象逻辑没有改变。

所以:

mutable

非常适合。


六、mutable和普通变量的区别

变量const函数中能否修改
普通成员变量 ❌不能
mutable成员变量 ✅可以

例如:

class A
{

int x;

mutable int y;

void test() const
{

x++; //错误

y++; //正确

}

};


七、mutable 和 const 对象

看一个更特殊情况:

class Student
{

public:

mutable int score;

};

int main()
{

const Student s;

s.score=100;

}

居然可以!

为什么?

因为:

score是mutable

所以:

即使对象是const:

它仍然允许修改。


八、mutable的底层理解

同学们可以这样理解:

普通变量:

对象
|
+— age
|
+— name

const对象:

全部锁住


但是:

mutable:

对象
|
+— age 🔒
|
+— name 🔒
|
+— cache 🔓

给某些成员变量开一个“小后门”。


九、什么时候使用mutable?

在实际C++开发中,主要有三个用途:


1. 统计信息

例如:

mutable int count;

记录:

  • 调用次数

  • 点击次数

  • 访问次数


2. 缓存结果

例如:

mutable double result;

保存:

计算结果。


3. 多线程中的锁

高级C++中:

经常看到:

mutable mutex m;

因为:

即使函数是const:

也可能需要加锁。


十、信奥竞赛中需要掌握吗?

对于:

GESP/CSP-J阶段:

通常:

不考 mutable 的复杂应用。

但是:

理解它有两个价值:

  • 帮助理解 const

  • 为以后学习C++ STL源码打基础

  • 例如:

    以后看:

    string
    vector
    map

    源码时:

    会看到:

    mutable


    十一、一句话总结

    记住一句口诀:

    const 是“大门锁”,禁止修改;
    mutable 是“小抽屉”,允许特殊修改。

    或者:

    const对象:
    大部分不能改变

    mutable变量:
    特殊变量可以改变


    最后的类比:

    爸爸说:

    “我的书房不能乱动。”

    这是:

    const


    但是:

    爸爸允许:

    “墙上的日历可以每天更新。”


    这个日历:

    就是:

    mutable


    所以:

    mutable不是破坏const,而是告诉编译器:

    “这个变化不属于对象本质变化,只是额外记录信息。”

    对于初学C++的小学生,可以把 mutable 放在学习路线:



    this指针

    const成员函数

    mutable

    拷贝构造

    运算符重载

    这是面向对象理解中的一个重要小知识点。


    赞(0)
    未经允许不得转载:171主机测评 » 小学生学C++编程语法知识(C++中的 mutable 详解)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址