コンパイラーの検査をかいくぐる(承前)


と、いう訳で、const検査をかいくぐる話の続きです。

const_cast

constじゃないものをconstみたいにする、…あれ?…constをconstじゃないみたいに するのかな、考え出すとどっちだかわからなくなるけど、 こういう問題のために用意されているのが、 mutableconst_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(&param);
                // 以下省略
        }

困った例(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なんか最初から無かった方がよかった、ということに なりかねません。