Heim > Backend-Entwicklung > C++ > Wie erstelle ich C-Objekte aus einer Zeichenfolge, die ihren Klassennamen enthält?

Wie erstelle ich C-Objekte aus einer Zeichenfolge, die ihren Klassennamen enthält?

Patricia Arquette
Freigeben: 2024-12-20 01:33:10
Original
1070 Leute haben es durchsucht

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

Wie instanziiere ich Objekte aus einer Zeichenfolge, die ihren Klassennamen enthält?

Im angegebenen Code erstellt eine BaseFactory-Klasse Objekte verschiedener abgeleiteter Klassen basierend auf einer Zeichenfolge, die ihren Klassennamen darstellt. Die Factory erfordert jedoch das manuelle Hinzufügen von if-Anweisungen für jede mögliche abgeleitete Klasse. Man könnte sich fragen, ob es eine Alternative zu diesem ausführlichen Ansatz gibt, ähnlich der Reflection-Funktion von C#.

Leider gibt es keinen automatisierten Mechanismus

Leider verfügt C nicht über einen Mechanismus für die automatische Erstellung von Objekten der zur Laufzeit angegebenen Typen. Es ist jedoch möglich, die Zuordnung selbst vorzunehmen:

Typzuordnung

Sie können eine Zuordnung erstellen, die für jeden Klassennamen eine Funktion speichert, die ein Objekt erstellt dieser Klasse:

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>;
Nach dem Login kopieren

Dann können Sie die Objekte auch instanziieren Hilfe:

return map[some_string]();
Nach dem Login kopieren

Typregistrierung

Eine alternative Lösung besteht darin, Typen zu erlauben, sich selbst zu registrieren:

// 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");
Nach dem Login kopieren

Sie können auch Makros definieren zur Typregistrierung:

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

#define REGISTER_DEF_TYPE(NAME) \
    DerivedRegister<NAME> NAME::reg(#NAME)
Nach dem Login kopieren

Für Typen, die keine gemeinsame Basisklasse haben, können Sie die Variante verwenden boost::variant als Rückgabetyp der Funktion:

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;
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie erstelle ich C-Objekte aus einer Zeichenfolge, die ihren Klassennamen enthält?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage