可能重复:
C++ 'mutable' keyword
When have you used C++ 'mutable' keyword?
我理解mutable
的含义及其使用方式,我想知道的是它存在的真正动机是什么。我不认为唯一的动机是绕过this
成员函数中const
的不变性我认为还有更多内容。
我不认为这只是在设计不良的系统中绕过问题的手段吗?或者是吗?
原始问题的明显分支何时使用mutable
即使在一个好的设计中也有意义?
答案 0 :(得分:11)
动机 实际上是绕过this
方法中const
的不变性(语法级别)。 const
是语义检查,由编译器在语法上进行验证。任何在语义上不修改对象的状态的操作都应该是const
,但在某些情况下,实现需要更改子对象,mutable
是告诉语句的语法工具。编译器,该特定成员不是对象的 state 的一部分,因此可以在const
方法中进行修改。
例如,如果没有mutable
,则无法将存储为成员变量的互斥锁锁定在语义上不会修改对象状态的访问器中,因为编译器中的语法检查会抱怨您是修改互斥锁。还有其他一些激励性的例子,例如memoization,其中实现细节(优化,线程安全)意味着在不修改对象的可见状态的方法中更改成员变量。
答案 1 :(得分:8)
mutable
是将按位const与逻辑const分开的一部分。
基本上,编译器实现的内容称为按位const:it
如果你试图修改const中实际对象的位,则会抱怨
功能,但不是。当你写一堂课时,你想要
实现逻辑const:const函数不修改observable
对象的值(类的作者定义的是什么
可观察的价值)。大多数情况下,这是一个不修改东西的问题,
即使你可以(例如通过指针访问的部分值),
但每隔一段时间,实际物体中就有“位”(如图所示)
编译器)不是可观察值的一部分:缓存值
懒惰计算是经典的例子,但可以想象其他人:
例如,移动链接列表中的元素
列表中的元素需要更新指向previous和
next(但是列表中元素的位置不是其中的一部分
元素的可观察价值。)
答案 2 :(得分:4)
一个常见的需求是实施memoization。对于外部世界,函数调用不是修改对象状态,而是在内部必须更新memoization缓存。将缓存标识为mutable
可以实现。
答案 3 :(得分:0)
动机是绕过this
的不变性。关键是对象的某些部分可能必须进行变异,但不会对对象的可见状态做出贡献。有时修改只是一个实现细节,在界面中不应该真正可见(并且可能会发生变化。
锁定数据结构的示例是mutices
。即使对于const
方法,您也可能需要锁定结构,以确保在读取结构时没有其他线程正在修改结构。如果方法没有改变对象,那么它应该在逻辑上为const
(暴露通过锁定和解锁对象所做的更改似乎很愚蠢),因此您需要制作互斥锁mutable
。