C++要点(1)mutable关键字

mutable语义

在C++中,mutable是为了突破const的限制而设置的。
被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改。

例如:

#include <iostream>

class Tester
{
    public:
        Tester(int x, int y) : a_normal(x),b_mutable(y)
    {}
        void printAll() const
        {
            std::cout << "a_normal=" << a_normal << "; b_mutable=" << b_mutable << std::endl;
        }

        int a_normal;
        mutable int b_mutable;
};

int main()
{
    const Tester tst(2,3);
    tst.a_normal = 22;
    tst.b_mutable = 33;

    tst.printAll();

    return 0;
}

编译报错,报错信息如下

test4mutable.cpp: In function ‘int main()’ :test4mutable.cpp:20: error: assignment of data-member ‘Tester::a_normal’ in read-only structure

我们将报错的那行代码注释掉后重新编译,通过运行。

mutable在类中只能修饰非静态数据成员。

const语义

const修饰的变量在任何情况下它的值都不会被改变。
const修饰的函数不能直接或间接地改变任何函数体以外的变量的值,即使调用一个可能造成这种改变的函数也不行。

关于const关键字的详细解析请参考博文:const关键字浅析

mutable和const的关系

mutable修饰的变量将永远处于可变的状态,即使在一个const函数中。
所以mutable和const形成了一个对称的定义:一个永远不变,一个永远可变。

那么有3个问题需要考虑:

  1. 为什么要保护类的成员变量不被修改?
  2. 为什么mutable要突破const的封锁?
  3. 使用const和mutable关键字的必要性。

保护类的成员变量不在成员函数中被修改,是为了保证模型的逻辑正确,通过用const关键字来避免在函数中错误的修改了类对象的状态。并且在所有使用该成员函数的地方都可以更准确的预测到使用该成员函数的带来的影响。

而mutable则是为了能突破const的封锁线,让类的一些次要的或者是辅助性的成员变量随时可以被更改。

没有使用const和mutable关键字当然没有错,const和mutable关键字只是给了建模工具更多的设计约束和设计灵活性,而且程序员也可以把更多的逻辑检查问题交给编译器和建模工具去做,从而减轻程序员的负担。

mutable提供的灵活性

如果类的成员函数不会改变对象的状态,那么这个成员函数一般会声明成const的。但是,如果希望在const函数中修改一些和类状态无关的数据成员,那么可以使用mutable修饰这个成员。
明智地使用mutable关键字,可以向用户隐藏实现细节,而无需使用不确定的东西,提高代码质量。

例如:

#include <iostream>

class Tester
{
    public:
        Tester(int x, int y) : a_normal(x),b_mutable(y), printCount(0)
    {}
        void printAll() const
        {
            std::cout << "a_normal=" << a_normal << "; b_mutable=" << b_mutable << std::endl;
            std::cout << "print " << ++printCount<< " times" << std::endl << std::endl;
        }

        int a_normal;
        mutable int b_mutable;
        mutable int printCount;
};

int main()
{
    const Tester tst(2,3);
    tst.b_mutable = 33;

    tst.printAll();
    tst.printAll();
    tst.printAll();

    return 0;
}

在上例中,printAll函数是一个const函数,但是希望在打印的同时,记录打印次数,因此,在类中增加了一个成员变量printCount,该成员变量和类本身的状态无关,并且需要在printAll函数中改变,因此使用mutable关键字修饰,实现了统计打印次数的目的。

执行结果如下图所示:

这里写图片描述




参考资料:
C/C++要点全掌握(五)——mutable、volatile

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值