(この質問は反射に関連していますが、実際には反射についてではありません)
このクラスの階層 ( とclass A
などclass B : public A
) があり、インスタンス固有のデータに加えて、クラス固有のデータをすべてのインスタンスで共有したいと考えています。たとえばFunnyClassName
、クラスごとに文字列が必要だとします。
次のように、クラスごとのデータに非仮想ゲッターを使用できるようにしたいと考えています。
/*can it be static? */ const std::string& A::GetFunnyName();
最も重要なことは、クラスを継承する際にボイラープレート コードをまったく使用しないか、できるだけ少なくしたいということです。class A
getter は(クラス階層のルート) に一度実装されます。クラス B は、別の方法でその FunnyClassName を指定する必要があります。
クラスの型ハッシュをキーとして使用する Multiton オブジェクトが合理的な解決策の基礎になる可能性があることが示唆されています (たとえば、SO に関するここでの質問で間接的に)。そうですか?これを行う「標準」コードはありますか (STL または Boost など)? 関連する別のアプローチはありますか?
注:
- これは不可能だと思いますか?この質問とこの(簡潔な)回答を参照してください。しかし、一部のコメンターやレスポンダーが示唆するように、非静的ゲッターが必要になる場合があり、すべてのクラスでゲッターを書き換える必要がない (つまり、RTTI を使用する) というより弱い制約を作成する必要があります。
- C++ に静的仮想データ メンバーがある場合、これは些細なことです -
virtual static const std::string FunnyName
。静的仮想メソッドでも可能ですが、基本クラスに実装されているゲッターのみの要求を削除した場合に限ります。と のようなものが/* static??*/ static const std::string& A::GetFunnyName() { return "Aye"; }
あり/* static??*/ const std::string& B::GetFunnyName() { return "Bee"; }
ます。 - テンプレート化されたクラスの場合には特に興味はありませんが、それにも対処したいのであれば、それは素晴らしいことです。
- FunnyName() は単なる例です。かもしれません
const Thing& GetFunnyThing()
。typeid.name() からのクラスの名前、またはそのデマングリングなどは必要ありません。 - C++11 は問題ありませんが、C++03 でのソリューションの方が優れています。C++14 は使用しないでください。