クラス名文字列からのオブジェクトのインスタンス化
C では、明示的なマッピングを行わずにクラス名を含む文字列からオブジェクトをインスタンス化することはできません。 。この制限は、コンパイル時に型を認識する必要があるという C の静的な性質に起因します。
オプション 1: テンプレートを使用した手動マッピング
テンプレート関数を作成できます。インスタンス化するクラスごとに、クラス名を対応するテンプレート関数にリンクするためのマップを作成します。例:
template<typename T> Base* createInstance() { return new T; } map_type map; map["DerivedA"] = &createInstance<DerivedA>; map["DerivedB"] = &createInstance<DerivedB>;
オブジェクトをインスタンス化するには、次を使用します:
return map[some_string]();
オプション 2: ランタイム型登録
クラスを使用できます。静的メカニズムに自身を登録し、インスタンスを動的に取得します。これには、シングルトン マップを使用してクラス名と関数のマッピングを保存することが含まれます。以下に例を示します。
struct BaseFactory { static Base * createInstance(std::string const& s) { auto it = getMap()->find(s); return it != getMap()->end() ? it->second() : nullptr; } static std::map<std::string, std::function<Base*()>> * getMap() { if (!map) { map = new std::map<std::string, std::function<Base*()>>; } return map; } private: static std::map<std::string, std::function<Base*()>> * map; }; template<typename T> struct DerivedRegister : BaseFactory { DerivedRegister(std::string const& s) { getMap()->insert({s, &createInstance<T>}); } }; class DerivedB { private: static DerivedRegister<DerivedB> reg("DerivedB"); };
このメソッドにより、実行時にクラスを自動登録できます。
オプション 3: Boost Variant
共通の基本クラスを持たない無関係なクラスの場合は、Boost バリアントを使用できます。 library:
typedef boost::variant<Foo, Bar, Baz> variant_type; template<typename T> variant_type createInstance() { return variant_type(T()); } typedef std::map<std::string, variant_type (*)()> map_type;
この手法により、単一の文字列からさまざまな型をインスタンス化できます。
結論として、C にはクラス名文字列からオブジェクトをインスタンス化するための組み込みメカニズムがありません。ただし、テンプレート、ランタイム登録、または Boost バリアント ライブラリを使用すると、同様の機能を実現できます。
以上がクラス名の文字列から C オブジェクトをインスタンス化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。