C++11 Standard § 7.1.2/11 The mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const.
关于 mutable 的一篇博客:C++'s mutable and conceptual constness
mutable啊,忘了?
解决
那你只有再套一层封装了,你现在的要求就是在封装的过程中使用封装后的结果。
毕竟,要看你到底不希望哪部分代码对那个变量赋值,先分清楚哪部分是用户代码,再来讨论访问权限的问题。
如果你所说的“赋值”是指初始化的话(赋初值),一个类的数据成员是不可能不被初始化的。如果这个数据成员没有在构造函数的初始化列表里进行初始化,那么编译器会对其进行默认初始化(default initialize)。所以不可能仅在某个成员函数内才初始化该类的数据成员。
如果你所说的“赋值”不是指初始化,而是指改变现有值,那么可以通过在数据成员声明中添加
mutable
来做到。但是,使用
mutable
的时候要注意:在改变声明中包含
mutable
的数据成员的时,不应该影响这个类的外在状态。换句话说:
声明中包含
mutable
的数据成员应该用于描述类内部的状态,这些数据成员的改动不会从逻辑上改变这个类的状态。比如用于程序调试的成员、用于缓存(或者说被延迟赋值)的成员、用于访问检测的成员、用于互斥锁的成员等可以使用
mutable
,因为这些成员的改变并没有在逻辑上改变相应类的状态。举几个例子:
上面这个例子中,改变
visit_foo_count
并没有从逻辑上改变类C
的状态,从用户的角度看,每次调用c.foo()
的时候其效果都相同。这个例子同理,从用户的角度看,每次调用
mo.pi()
的时候结果都一样,用户并不知道只有在第一次调用时候才会进行pi_val
的计算,也不知道如果一次都不调用就不会计算pi_val
。引申
C++11 标准
关于
mutable
的一篇博客:C++'smutable
and conceptual constnessStack Overflow 的讨论:Purpose of the
mutable
keywordgcc可以使用
-fpermissive
选项关掉这个错误,然后这个错误就是警告了,如果你是别的编译器肯定有相应的选项,我也认为mutable
是一个很好的解决方案。