私はすべてのクラスが直接的または間接的に基底クラスBase
から派生し、名前を持つクラスライブラリを扱っています。ライブラリは、名前でオブジェクトを検索する機能を提供し、Base*
を返します。実行時にオブジェクトの型をポインタから基本クラスに戻す
次の例のように、dynamic_cast
を使用してすべての可能性をチェックせずに返されるオブジェクトの型を見つける方法はありますか?可能であれば、派生したクラスにテンプレートパラメータがあるので、これを避けたいと思います。これはかなりの可能性をもたらします。
テンプレートタイプを知らなくても、クラスタイプ(以下の例ではT1
またはT2
)を少なくとも見つけられればいいです。 dynamic_cast<T1<i_dont_care>*>
のようにしてください。
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {}
};
template <typename T> class T1 : public Base {};
template <typename T> class T2 : public Base {};
Base *find_by_name() {
return new T2<int>();
}
int main() {
Base *b = find_by_name();
if (T1<int> *p = dynamic_cast<T1<int>*>(b)) {
cout << "T1<int>" << endl;
// do something meaningful with p
} else if (T1<double> *p = dynamic_cast<T1<double>*>(b))
cout << "T1<double>" << endl;
else if (T2<int> *p = dynamic_cast<T2<int>*>(b))
cout << "T2<int>" << endl;
else if (T2<double> *p = dynamic_cast<T2<double>*>(b))
cout << "T2<double>" << endl;
else
cout << "unknown" << endl;
delete b;
return 0;
}
上記の例は簡略化されています。それぞれif
で私はp
と意味のある何かをしたいと思います。
私はこれが最初から悪いデザインであることを認識していますが、私はこのライブラリに悩まされていますし、その実装を変更する方法もありません。
は、 'B'は、それを行うためのメンバーを持っている必要があります。また、 'typeid(* b).name()'を調べることもできます。 –
あなたの 'p'は全て冗長です。' if(dynamic_cast *>(b)) ' –
' Base'は本当に他のメンバーを持っていませんか?これは、ライブラリが提供すべき機能のようなものです。普通のポインタでできることはあまりありません。 – juanchopanza