プロが教える店舗&オフィスのセキュリティ対策術

namespace内のメンバをprivateのようにしたいときは、無名名前空間を使うとあったのですが、ヘッダオンリーライブラリでこれを実現する方法はありませんか?

紹介されている方法
//hoge.h
namespace Hoge{
void hoge();
}

//hoge.cpp
namespace Hoge{
namespace{
void hogeHelper(){}
}
void hoge(){hogeHelper();}
}

上記の方法ではhoge.cpp以外からはhogeHelperにはアクセスできなくなるとのことです。

しかし、ヘッダオンリーライブラリで次のように書いている場合にHoge::hogeHelperとしてアクセスできてしまいます。

//hoge.h
namespace Hoge{
namespace{
inline void hogeHelper(){}
}
inline void hoge(){hogeHelper();}
}

(ライブラリを書き換えない限り)hogeHelperへのアクセスを禁止する方法はありませんか?

A 回答 (3件)

まあこの筋だとどうやっても「エラーメッセージがわけわからん」状態になるのは避けられないでしょうねぇ. ソースで


#define DO_NOT_USE_AFTERWARD(name) なんか
のようなマクロを定義して明確にすれば多少「ごまかし」感は減るけど....

あるいは, いっそあきらめて
すべてのメンバーが private かつ static な class
を作るとか. たとえば,
namespace Hoge {
void hoge();
class detail {
static void hogeHelper() { }
friend void hoge();
};
inline void hoge() { detail::hogeHelper(); }
}
みたいなイメージ.

この回答への補足

クラスのprivate staticメンバにしてfriend指定するのは思いつきませんでした。
これならエラーメッセージも理解しやすいです。

namespace Hoge内の他の関数やhoge()内から頻繁に使用される共通処理hogeHelper()を単体で外部から呼び出されたくないだけなので、classのprivate staticメンバで十分目的が果たせます。
namespaceのようにメンバを分割して記述できないことと、class名::を書くことを我慢すれば、namespaceにこだわる必要はないですね。

ありがとうございました。

補足日時:2011/07/28 16:54
    • good
    • 0

手元の g++ で試してみると


namespace Hoge{
namespace{
inline void hogeHelper(){}
}
inline void hoge(){hogeHelper();}
namespace{
inline namespace {
void hogeHelper();
}
}
}
で (「エラーになる」という意味で) 回避できている感じがします. つまり C++0x ならごまかせるかもしれない. そもそも名前空間が「アクセス制御」を意図しているわけじゃないので, 結局は「ごまかし」の感じが強いですが.

この回答への補足

hoge()内では1つめのhogeHelper()を参照しつつ、外からは定義されていない2つめのhogeHelper()を参照させるということですね。

inline namespaceはVC++2010ではエラーになってしまいました。

inlineを外した所、外からも1つめのhogeHelper()を参照してしまったらしく、リンクも通ってしまいました。

ここで、2個目のhogeHelper()をnamespace{namespace{}}から外に出してHoge内にしたところ、hoge()からは無名1つめのhogeHelper()を参照し、外からは2つめのhogeHelper()を参照したようで、みごとにリンクエラーにできました。

これはなかなかスマートな方法です。

さらに、リンクエラーではなくコンパイルエラーにするために、2つめのhogeHelper()を、もはや関数ではなく何でも良いのでnamespaceにしてしまいました。

namespace hogeHelper{}

これでHoge::hogeHelperによる関数へのアクセスを完全に禁止できそうです。

ありがとうございました。

補足日時:2011/07/28 11:49
    • good
    • 0

可能なら


#define hogeHelper
という技でごまかすとか.

この回答への補足

なるほど、そういう手もあるんですね。

回答ありがとうございます。

補足日時:2011/07/27 13:50
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!