C++のクラスについての質問です。
抽象クラスBASEを継承したクラスがCLASS1~CLASS10まであるとします。
同じクラスを継承したクラスのインスタンスをまとめて制御したいため、基底クラスのvectorを作って管理しています。
std::vector<BASE*> classes;
classes.push_back(new CLASS1());
classes.push_back(new CLASS2());
...
classes.push_back(new CLASS10());
たいした記述量ではないのですが、新しいクラスを定義した時に追加する処理が地味に面倒に感じます。
なので上記のようなプログラムをfor文で書けるようになればとても都合がいいのです。
具体的には、テキストファイルにクラス名のリストを書いておき、それを読み込みながらクラスのインスタンスを生成したいです。
C#ではできなくはないみたいなのですが、C++でこれを実現するのは無理でしょうか?
[C++]クラス名の文字列からそのクラスのインスタンスを生成する方法
- tk-xleader
- 記事: 158
- 登録日時: 14年前
- 連絡を取る:
Re: [C++]クラス名の文字列からそのクラスのインスタンスを生成する方法
C++には実行時に生成する型を決定してオブジェクトを作成する機構は言語には直接には組み込まれていませんので、一工夫が必要となります。C++でそれを実現しようと思えば、ちょっと面倒ですがstd::mapを応用すれば何とかなりそうです。
このまま使うには色々と問題があるコードですが、一応考え方のサンプルです。
// サンプルなので使用していないですが、newしたオブジェクトはstd::shared_ptrなどのスマートポインタで管理したほうが安全でしょう。
class IObjectBuilder{
public:
virtual IObject* Create() = 0;
};
template<typename T>
class ObjectBuilder : public IObjectBuilder{
public:
virtual T* Create(){return new T;}
};
#define REGISTER_ARGS(TYPE) #TYPE,new ObjectBuilder<TYPE>
class BuilderFromString{
std::map<std::string,IObjectBuilder*> builders;
public:
void Register(const string& ty_name,IObjectBuilder* builder){
builders.insert(std::make_pair(ty_name,builder));
}
IObject* Create(const std::string& ty_name){
std::map<std::string,IObjectBuilder*>::iterator itr = builders.find(ty_name);
if(itr == builders.end())return 0;
return (*itr).second->Create();
}
};
// 使用例
BuilderFromString builderfromstring;
builderfromstring.Register(REGISTER_ARGS(CLASS1));
builderfromstring.Register(REGISTER_ARGS(CLASS2));
builderfromstring.Register(REGISTER_ARGS(CLASS3));
builderfromstring.Register(REGISTER_ARGS(CLASS4));
// ……必要なクラスを登録していく。
IObject* object1 = builderfromstring.Create("CLASS1");
IObject* object2 = builderfromstring.Create("CLASS2");