ホームページ > バックエンド開発 > C++ > クラス名を含む文字列から C オブジェクトを作成するにはどうすればよいですか?

クラス名を含む文字列から C オブジェクトを作成するにはどうすればよいですか?

Patricia Arquette
リリース: 2024-12-20 01:33:10
オリジナル
1016 人が閲覧しました

How to Create C   Objects from a String Containing Their Class Name?

クラス名を含む文字列からオブジェクトをインスタンス化する方法?

指定されたコードで、BaseFactory クラスはさまざまな派生クラスのオブジェクトを作成しますクラス名を表す文字列に基づきます。ただし、ファクトリでは、考えられる派生クラスごとに if ステートメントを手動で追加する必要があります。 C# のリフレクション機能と同様、この冗長なアプローチに代わるものはないのかと疑問に思う人もいるかもしれません。

残念ながら、自動化されたメカニズムはありません

残念ながら、C にはメカニズムがありません。実行時に指定されたタイプのオブジェクトを自動作成する場合。ただし、マッピングを自分で行うことも可能です。

型マッピング

クラス名ごとに、オブジェクトを作成する関数を格納するマップを作成できます。そのクラスの:

template<typename T> Base * createInstance() { return new T; }

typedef std::map<std::string, Base*(*)()> map_type;

map_type map;
map["DerivedA"] = &amp;createInstance<DerivedA>;
map["DerivedB"] = &amp;createInstance<DerivedB>;
ログイン後にコピー

その後、オブジェクトもインスタンス化できますhelp:

return map[some_string]();
ログイン後にコピー

型の登録

別の解決策は、型自体を登録できるようにすることです:

// w base.hpp:
template<typename T> Base * createT() { return new T; }

struct BaseFactory {
    typedef std::map<std::string, Base*(*)()> map_type;

    static Base * createInstance(std::string const&amp; s) {
        map_type::iterator it = getMap()->find(s);
        if(it == getMap()->end())
            return 0;
        return it->second();
    }

protected:
    static map_type * getMap() {
        // nigdy nie usuwane (istnieje do zakończenia programu)
        // ponieważ nie możemy zagwarantować poprawnej kolejności usuwania
        if(!map) { map = new map_type; }
        return map;
    }

private:
    static map_type * map;
};

template<typename T>
struct DerivedRegister : BaseFactory {
    DerivedRegister(std::string const&amp; s) {
        getMap()->insert(std::make_pair(s, &amp;createT<T>));
    }
};

// w derivedb.hpp
class DerivedB {
    ...;
private:
    static DerivedRegister<DerivedB> reg;
};

// w derivedb.cpp:
DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
ログイン後にコピー

マクロを定義することもできます型登録の場合:

#define REGISTER_DEC_TYPE(NAME) \
    static DerivedRegister<NAME> reg

#define REGISTER_DEF_TYPE(NAME) \
    DerivedRegister<NAME> NAME::reg(#NAME)
ログイン後にコピー

共通の基本クラスを共有しない型の場合は、バリアントを使用できます。関数の戻り値の型として boost::variant:

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 オブジェクトを作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート