適当な構造体 TTest のインスタンスが const で修飾されているとき(const TTest x),そのメンバに値を代入したい,でもそのためだけにそのインスタンス(x)から const を外すのは嫌,という場合を考えよう.あるいは const メンバ関数(メンバ変数を変更しないメンバ関数)で,テンポラリなメンバ変数を変更したい,でもそのメンバ関数を非 const にするのは嫌,という場合でもいい.結論から言えば, mutable を使うと解決できる.
構造体とそのインスタンス
struct TTest
{
int a;
int b;
};
const TTest x= {10,2};
を考える. x は const 修飾されているから,当然
x.a=5;
のようなコードはエラー. g++ なら
error: assignment of data-member 'TTest::a' in read-only structure
というエラーを吐く.むりやり値を代入するには,
((TTest&)x).a= 5;
// or
const_cast<TTest&>(x).a= 5;
のようなコードを書くと言う手段がある.前者は C 言語流のむりやりキャストで,後者は C++ のキャスト.後者の方が const を外すことを意識してプログラムしている,あるいはコードを読むと意識的に const を外したことがわかるという点でベターだ.しかし,いずれも乱暴なコードで,危険性もある.変数 x の宣言を見ると,この変数が変わることはない,と思うからだ.
そこで,メンバ変数 a については,書き換えてもよいことにする.例えばテンポラリ変数(一時的に使われる変数)のような場合だ.具体的には ,宣言の頭に mutable キーワードをつけて,
struct TTest
{
mutable int a;
int b;
};
と書く.これによって, TTest のインスタンスが const であっても a を変化させてもよい,ということをコンパイラに伝えることができる.つまり,
const TTest x= {10,2};
x.a=5;
がエラーではなくなる.
このように mutable をつける方法は,キャストの方法よりもいくらか安全だ.なぜなら,構造体 TTest のメンバを見ると a がインスタンスが const でも変更される可能性があることに気づくからだ. const 修飾したメンバ関数から mutable 修飾したメンバ変数を変更することも可能である.