这两个术语有什么区别,为什么我需要mutable
?逻辑与物理常数的区别
回答
当对象中有可以被视为“内部”的字段时,即任何类的外部用户无法确定这些字段的值时,您需要mutable
。尽管实例被认为是常量,即不改变,但该类可能需要写入这些字段。
考虑一个硬盘;它的缓存就是这种状态的一个例子。缓存为,写入,当数据为时,从实际磁盘读取。
这是不可能用C++干净地表达而不使相应的成员mutable
,即使在标记为const
的方法中也可以改变它们。正如在评论中指出的那样,你总是可以接触锤子并使用const_cast<>
来移除const
-,但这当然是作弊的。 :)
“物理”常量来自声明一个对象const
,原则上可以通过将对象放在只读存储器中强制执行,因此它不能更改。试图改变它会导致未定义的行为;它可能会改变,或者它可能不会改变,或者它可能引发保护错误,或者它可能会熔化内存芯片。
“逻辑”常量来自声明引用或指针const
,并由编译器强制执行。对象本身可能是“物理”常量,也可能不是,但引用不能用于在没有强制转换的情况下对其进行修改。如果对象不是“物理”常量,则C++允许您修改它,使用const_cast
来规避保护。
A mutable
即使类对象本身(或用于访问它的引用或指针)为const
,也可以修改类成员。这样做的好用例子是在读取操作期间必须锁定的互斥锁,以及用于存储昂贵读取操作结果的缓存。在这两种情况下,操作本身应该是const
函数(因为它不影响对象的可见状态),但它需要修改互斥锁或缓存,因此这些操作必须是mutable
。它也可能被滥用,使得物体在逻辑上不可见时发生明显的变化,因此小心使用它;如果它们不构成外部可见状态的一部分,则仅声明成员mutable
。
+1,非常好的解释。 – Dan 2010-10-01 13:44:10
这样读得非常好:-),但是非常错误:-(。“”物理“常量来自声明一个对象const” - “const”不能保证你的“物理常量”:成员可能仍然是“可变的”并在运行时更改,因为这是允许的,编译器/链接器等不会将这些对象默认放置在只读存储器中,即使它们是“静态常量”,如果它们被迫通过某些非标准的编译器/链接器/加载器标志,然后程序员必须手动避免'mutable'成员。你在对象和指针/引用之间绘制的区别实际上是不相关的。 – 2011-07-28 01:49:16
@TonyDelroy-我带着Mike的回应,只有记忆“作为一种修辞(和修辞有效)的陈述来表达关于物理和逻辑”常量“之间差异的观点,而不是表明编译者会真正做到这一点;他也没有声明编译器会*做这也是我不同意他的disti指针和引用之间的连接是无关紧要的。答案在概念上是坚实和正确的。在我看来,TonyDelroy在说他的答案“非常错误”时并不正确。 – 2012-05-29 05:02:54
- 1. 逻辑常数和物理常量性
- 2. 逻辑与物理设计
- 3. 逻辑SQL和物理SQL有什么区别?
- 4. 物理和逻辑IO计
- 5. 逻辑和物理组件
- 6. 逻辑和物理寻址
- 7. 逻辑和物理模型
- 8. 物理量子位和逻辑量子位之间有什么区别?
- 9. 物理或逻辑分离我的dll?
- 10. 寻呼和逻辑和物理地址
- 11. 物理缓存VS逻辑缓存
- 12. 封装常见异常处理逻辑
- 13. 语义错误与逻辑错误之间的区别
- 14. 虚拟处理器和逻辑分区
- 15. RDD分区逻辑
- 16. 异常处理和程序逻辑
- 17. 与逻辑掩码MATLAB小区指派
- 18. 放入购物车数量逻辑RoR
- 19. 逻辑清理
- 20. 会员与物业之间的区别?
- 21. 整数区间的逻辑计算
- 22. AndEngine物理编辑器加载级别
- 23. 切换分区的逻辑
- 24. CakePHP异常逻辑
- 25. 逻辑,如果再别的
- 26. 与indexpathforselectedrow数组逻辑
- 27. SQL Server并行逻辑处理器或物理内核
- 28. 的LINQ与逻辑
- 29. 与逻辑
- 30. Numpy.where与逻辑
另一个这样的例子是不同线程共享的对象中的互斥。读取操作不会修改对象,但必须在此过程中获取并释放互斥锁。在操作过程中,互斥成员对象会发生明显变化,即使操作的结果不会改变对象本身。即使内部元素发生变化,如果感知状态保持不变,对对象的操作也是常量。 – 2010-09-30 12:25:09
可以请你给我一个小例子(代码),它显示了我可以做什么与mutable和不能与const,这也显示了逻辑和物理const'ness之间的区别我在谷歌找到一些解释但无法找到好例如,缓存有点难以理解 – rookie 2010-09-30 12:34:43
_这是不可能用C++表达而不使相应的成员变为可变的。该陈述是不正确的,它可以通过转换对象或成员来消除常量,从而完成(并在过去)。关键字'mutable'出现后,当逻辑常量的概念被实现时,因为程序员为了获得这种效果而去除了对象的常量,使得它更易于维护和强制执行。参见[这里](http://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_025.html)。 – Adrian 2014-06-04 20:08:50