const をふりかけた関数の中からは、原則としてデータメンバーの変更は許されていない。そんな const 型の関数の中から変更できるデータメンバーを宣言するのに使われるのが特殊調味料:mutable である。
さっそく調理実習。
#include <iostream>
using namespace std;
class TypeA {
public:
TypeA(int n = 0, double a = 0.) : fN(n), fA(a) {}
void Print()
{
if (fN == 0) fN = 1;
if (fA == 0.) fA = 1.;
cerr << fN << " " << fA << endl;
}
void Print() const
{
if (fN == 0) fN = 2; // OK: fN is mutable
// if (fA == 0.) fA = 2.; // NG (コンパイルエラー)
cerr << fN << " " << fA << endl;
}
private:
mutable int fN;
double fA;
};
int main()
{
TypeA v;
const TypeA c = v;
v.Print(); // 1番目の Print() が呼ばれる
c.Print(); // 2番目の Print() が呼ばれる
return 0;
}
この例では、2番目の const 型の Print() 関数の中で fA の値を変更しようとするとコンパイルエラーとなる。これは、const 型関数の中では this が const 属性を持っているからである。しかし、同じ const 型関数の中での fN の変更はコンパイルエラーにならない。これは fN が mutable 宣言されているからである。