正如John Dibling 所说,将更改的字段标记为可变。重要的部分在 ypnos 的评论中:“不要真正改变对象的状态”(正如外界所感知的那样)。也就是说,在 const 方法调用之前和之后的任何方法调用都必须产生相同的结果。否则你的设计有缺陷。
一些有意义的事情是可变的:
互斥锁不是对象状态的一部分,它们只是保证数据完整性的阻塞机制。从您的类中检索值的方法确实需要更改互斥锁,但是在执行 const 方法之后,您的类数据和状态将与之前完全相同。
对于缓存,您必须考虑仅对检索成本高且假定不会更改的数据有意义的数据(例如 DNS 结果)。否则,您可能会将过时的数据返回给您的用户。
在 const 方法中不应该更改的一些内容:
- 任何修改对象状态的东西
- 影响此或其他方法结果的任何内容
执行 const 方法的类的任何用户都将假定您的类(从外部世界看)在执行期间不会改变。如果它不一样,那将是相当误导和容易出错的。举个例子,假设一个 dump() 方法改变了一些内部变量 -state, value- 并且在调试过程中你的类的用户决定在给定的点 dump() 你的对象:你的类在跟踪和没有跟踪时的行为会有所不同: 完美的调试噩梦。
请注意,如果您执行惰性优化,则必须执行它们才能访问不可变数据。也就是说,如果您的界面规定在构建期间您将从数据库中检索一个元素,该元素以后可以通过常量方法访问,那么如果您对数据进行延迟获取,您最终可能会遇到用户构造您的对象的情况保留旧数据的副本,修改数据库,然后决定将以前的数据恢复到数据库中。如果您执行了延迟提取,您最终会丢失原始值。如果在程序执行期间不允许修改配置文件,则相反的示例是配置文件解析。您可以避免将文件解析到需要的位置,因为您知道在开始或稍后执行读取将产生相同的结果。