Können Objekte aus Klassennamen-Strings in C instanziiert werden?
Gibt es in C einen Mechanismus, um Objekte aus Strings zu instanziieren, die ihre Klassennamen darstellen Dadurch entfällt die Notwendigkeit, explizit if-else-Anweisungen für jede potenziell abgeleitete Klasse in einer Factory zu definieren Klasse?
Problem:
Betrachten Sie die folgende Klassenstruktur:
class Base; class DerivedA : public Base; class DerivedB : public Base; // etc...
Und eine entsprechende Factory-Klasse, BaseFactory, die Instanzen von abgeleiteten erstellt Klassen basierend auf einer angegebenen Klassennamenzeichenfolge:
class BaseFactory { public: BaseFactory(std::string &sClassName) { msClassName = sClassName; }; Base * Create() { if(msClassName == "DerivedA") { return new DerivedA(); } else if(msClassName == "DerivedB") { return new DerivedB(); } // etc... }; private: string msClassName; };
Dieser Ansatz erfordert jedoch die explizite Angabe jeder darin enthaltenen abgeleiteten Klasse BaseFactory, die mit zunehmender Anzahl abgeleiteter Klassen umständlich werden kann.
Lösung:
Im Gegensatz zu Sprachen wie C# bietet C von Natur aus keinen Mechanismus zum dynamischen Erstellen Objekte basierend auf Laufzeittypinformationen. Um eine ähnliche Funktionalität zu erreichen, kann man erwägen, eine Zuordnung zwischen Klassennamen und Objekterstellungsfunktionen zu erstellen:
template<typename T> Base * createInstance() { return new T; } typedef std::map<std::string, Base*(*)()> map_type; map_type map; map["DerivedA"] = &createInstance<DerivedA>; map["DerivedB"] = &createInstance<DerivedB>;
Mit dieser Zuordnung wird die Objektinstanziierung zu:
return map[some_string]();
Alternativ kann man sich registrieren abgeleitete Klassen automatisch während der Programminitialisierung:
template<typename T> struct DerivedRegister : BaseFactory { DerivedRegister(std::string const& s) { getMap()->insert(std::make_pair(s, &createT<T>)); } }; // in derivedb.hpp class DerivedB { ...; private: static DerivedRegister<DerivedB> reg; }; // in derivedb.cpp: DerivedRegister<DerivedB> DerivedB::reg("DerivedB");
Dieser Ansatz macht eine manuelle Klassenregistrierung überflüssig, da diese automatisch erfolgt, wenn die Klasse ist definiert.
Zusammenfassung:
Obwohl C die Objektinstanziierung aus Klassennamenzeichenfolgen nicht direkt unterstützt, bieten diese Techniken eine Möglichkeit, eine ähnliche Funktionalität zu erreichen, indem Klassennamen Objekten zugeordnet werden Erstellungsfunktionen oder durch Automatisierung des Registrierungsprozesses.
Das obige ist der detaillierte Inhalt vonKann C Objekte aus Klassennamenzeichenfolgen instanziieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!