Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中可变的动机+;_C++_Mutable - Fatal编程技术网

C++ C+中可变的动机+;

C++ C+中可变的动机+;,c++,mutable,C++,Mutable,可能重复: 我理解易变的含义以及它的使用方式,我想知道的是它存在背后的真正动机是什么。我不认为唯一的动机是在const成员函数中绕过this的不变性,我更认为还有其他原因。 我不认为这只是一种绕过设计糟糕的系统中的问题的方法?还是这样 原始问题的一个明显分支是,即使在一个好的设计中,何时使用mutable也有意义 一个常见的需求是实施。对于外部世界,函数调用不是修改对象状态,而是必须在内部更新备忘录缓存。将缓存标识为可变的允许这样做。动机实际上是绕过const方法中的此的不变性(语法级别)。

可能重复:

我理解易变的含义以及它的使用方式,我想知道的是它存在背后的真正动机是什么。我不认为唯一的动机是在
const
成员函数中绕过
this
的不变性,我更认为还有其他原因。
我不认为这只是一种绕过设计糟糕的系统中的问题的方法?还是这样


原始问题的一个明显分支是,即使在一个好的设计中,何时使用
mutable
也有意义

一个常见的需求是实施。对于外部世界,函数调用不是修改对象状态,而是必须在内部更新备忘录缓存。将缓存标识为可变的允许这样做。

动机实际上是绕过
const
方法中的
的不变性(语法级别)。
const
是一种语义检查,由编译器进行语法验证。语义上不修改对象状态的任何操作都应该是
const
,但在某些情况下,实现需要更改子对象,而
mutable
是一种语法工具,它告诉编译器这个特定的成员不是对象状态的一部分,因此可以在
const
方法中进行修改


例如,如果没有
mutable
,就无法锁定作为成员变量存储在语义上不修改对象状态的访问器中的互斥体,因为编译器中的语法检查会抱怨您正在修改互斥体。还有其他激励性示例,如memonization,其中实现细节(优化、线程安全)意味着在不修改对象可见状态的方法中更改成员变量。

激励性是绕过
的不变性。问题是,对象的某些部分可能必须进行变异,但不会影响对象的可见状态。有时,修改只是一个实现细节,不应该在接口中真正可见(并且可能会发生更改)


例如用于锁定数据结构的
mutices
。即使对于
const
方法,也可能需要锁定结构,以确保在读取结构时没有其他线程正在修改结构。如果该方法不更改对象,则在逻辑上应该是
const
(公开通过锁定和解锁对象所做的更改似乎很愚蠢),因此您需要将互斥锁设置为可变的

可变的
是将按位常量与逻辑常量分离的一部分。 基本上,编译器实现的是按位常量:it 如果试图修改常量中实际对象的位,则会发出投诉 函数,但不是其他。当您编写类时,您希望 实现逻辑常量:常量函数不会修改可观察值 对象的值(类的作者在其中定义 主要是,这是一个不改变事物的问题, 即使可以(例如,通过指针访问的部分值), 但实际对象中经常会有“位”(如图所示) 不属于可观察值的部分:缓存值 经典的例子是懒散计算,但我们可以想象其他例子: 插入式链表中的元素,例如,移动 列表中的元素需要更新指向上一个和下一个的指针 下一步(但列表中元素的位置不是
元素的可观察值)。

@DumbCoder:谢谢你的链接,但这并没有回答我的问题。这不是答案,更多的是你的分支问题。是的,它有-它提供了一个很好的例子,你可能想“绕过const”,而不是“设计糟糕的系统”@DumbCoder:这里的人们实际上没有阅读任何东西,只是到处跑来跑去,将发布的任何相关内容标记为重复。2票已经结束。当你指的是状态时,你指的是类用户观察到的行为?是指类本身的内部簿记,而不是它所具有的功能暴露给用户?@Als:不影响程序其余部分结果的任何内容。在Memorization中缓存的值与重新处理计算时得到的值完全相同,因此对于外部世界,无论是否缓存,结果都不会影响结果。重要的一点是
常量
一个语义标记,mutable是告诉编译器这个特定成员在语义上不是您的状态的一部分的语法结构。+1提到按位常量&逻辑常量概念,这是我公认的答案。