Irrlicht1.4から関数の修飾子が厳格化されます。例えば、get系の値取得関数は、メンバ変数の値を変更しないように、インターフェースクラスの段階からconst修飾子に縛られているのです。もちろん、不都合があるならメンバ関数をconst修飾子無しでオーバーライドしてしまえば、従来と変わりなく既存ソースを流用できます。
そこで、Irrlichtを使用している人も、その他の人も、ここでC++のconst修飾子についておさらいしましょう。
const char* foo(const char* str) const;
最初のconstから順番に説明していきます。
- 戻り値の値はfoo関数外部で変更されない
- 引数strの値はfoo関数内部で変更されない
- メンバ変数の値はfoo関数によって変更されない
プログラマが明示的に宣言することで、関数の挙動がある程度分かるようになります。そのため、後々の保守作業において効果を発揮します。うっかりメンバ変数の値を変更してしまい、謎の不具合に悩まされる事も少なくなるでしょう。
しかし、const修飾子は問題がない訳ではありません。特に上記例の3番目のconst宣言は厄介です。関数内でメンバ変数に手を加えるような実装がなされていると、コンパイルが通りません。関数設計を見直そうにも時間がない。バグ混入も恐ろしい。お手上げです。
そこで、mutable修飾子の出番です。これを用いてメンバ変数を宣言すると、特別にconst関数内でも値の変更が認められます。このアンチconstとも言うべき修飾子の存在は、本来期待される制限を歪めてしまう為、何だか本末転倒な感じではあります。最終手段として使うにとどめるのがいいでしょうね。
話は戻りますが、Irrlicht1.4βでもmutable修飾子が使われているところがありました。多少やりすぎなところもあり、IReferenceCounted::grub()にまでconst宣言がされてました。果たして、そこまで必要なのか疑問に思ってます。