我了解mutable
它的含义和使用方式,我想知道的是它存在的真正动机是什么。我不认为唯一的动机是绕过成员函数的不变性,this
我const
宁愿认为它还有更多的东西。
我不认为这只是绕过设计不良系统中问题的一种手段吗?或者是吗?
原始问题的一个明显分支,mutable
即使在一个好的设计中,什么时候使用才有意义?
我了解mutable
它的含义和使用方式,我想知道的是它存在的真正动机是什么。我不认为唯一的动机是绕过成员函数的不变性,this
我const
宁愿认为它还有更多的东西。
我不认为这只是绕过设计不良系统中问题的一种手段吗?或者是吗?
原始问题的一个明显分支,mutable
即使在一个好的设计中,什么时候使用才有意义?
动机实际上是绕过this
inconst
方法的不变性(语法级别)。这const
是由编译器在语法上验证的语义检查。任何语义上不修改对象状态的操作都应该是const
,但在某些情况下,实现需要更改子对象,并且mutable
是告诉编译器该特定成员不是对象状态的一部分的语法工具,因此可以在方法内部进行修改const
。
例如,如果没有mutable
,您将无法将存储为成员变量的互斥锁锁定在语义上不会修改对象状态的访问器中,因为编译器中的语法检查会抱怨您正在修改互斥锁。还有其他激励示例,例如 memoization,其中实现细节(优化、线程安全)意味着在不修改对象可见状态的方法中更改成员变量。
mutable
是将按位 const 与逻辑 const 分开的一部分。基本上,编译器实现的称为按位 const:如果您尝试在 const 函数中修改实际对象的位,它会报错,否则不会报错。当您编写一个类时,您希望实现逻辑 const:一个 const 函数不会修改对象的可观察值(类的作者定义什么是可观察值)。大多数情况下,这是一个不修改事物的问题,即使你可以(例如,通过指针访问的部分值),但每隔一段时间,实际对象(如编译器所见)中都有“位” t 部分可观察值:惰性计算的缓存值是经典示例,但可以想象其他示例:侵入式链表中的元素,例如,
一种常见的需求是实现memoization。对于外部世界,函数调用不会修改对象状态,但在内部必须更新记忆缓存。将缓存标识为mutable
允许这样做。
动机是绕过this
. 关键是对象的某些部分可能必须进行变异,但不会影响对象的可见状态。有时修改只是一个实现细节,不应该在界面中真正可见(并且可能会发生变化。
一个例子是mutices
锁定数据结构。即使是方法,您也可能需要锁定结构,const
以确保在您阅读结构时没有其他线程正在修改结构。如果该方法没有更改对象,它在逻辑上应该是const
(公开通过锁定和解锁对象所做的更改似乎很愚蠢),所以你需要制作 mutex mutable
。