と、いう訳で、const検査をかいくぐる話の続きです。
constじゃないものをconstみたいにする、…あれ?…constをconstじゃないみたいに するのかな、考え出すとどっちだかわからなくなるけど、 こういう問題のために用意されているのが、 mutableやconst_castというキーワードです。
このうちmutableは、const問題回避の小細工をしているところとは離れた場所に 書かなければならず、少々使いにくい気がするので、 const_castの方を説明します。 これは、「const問題回避のためのキャスト」という意味のキーワードなんですかね。 前回「困った例」として挙げたものは、次のように書けます。
困った例(1)
void Hoge::Open(const char * filePath)
{
::LibOpen(const_cast<char *>(filePath));
// 以下省略
}
困った例(1)の2つめ
void Hoge::Open(const char * filePath)
{
PARAM param;
param.path = const_cast<char *>(filePath);
::LibOpen(¶m);
// 以下省略
}
困った例(2)
== hoge.h ==
class Hoge
{
public:
virtual int GetMunya(void) const;
private:
boolean MunyaCalced;
int Munya;
};
== hoge.cpp ==
int Hoge::GetMunya(void) const
{
if (! MunyaCalced) {
const_cast<Hoge *>(this)->Munya = /* いろいろ計算 */;
const_cast<Hoge *>(this)->MunyaCalced = true;
}
return Munya;
}
どうでもいいことかも知れないけど、C++に追加された構文って、不等号が 目立ちますね。 テンプレートとか、streamio の<<とか(ちょっと違う?)。
これで一応、
というような場合が解決されました。 でも、今度は、
void Hoge::SetMunya(int munya) const
{
const_cast<Hoge *>(this)->Munya = munya;
}
みたいに
意味的にどう考えてもconstでない函数
にすらconstをつけることができてしまうんですね。 constの意味を知らず見よう見まねでconst_castを使い始めたプログラマーが、 こんなプログラムを大量生産し始めたら悲惨。 使い方を誤ると、constなんか最初から無かった方がよかった、ということに なりかねません。