Gibt es eine Möglichkeit, Objekte aus einer Zeichenfolge mit ihrem Klassennamen zu instanziieren?
Habe ich eine Datei: Base.h
class Base;
class DerivedA : public Base;
class DerivedB : public Base;
/*etc...*/
und eine weitere Datei: BaseFactory.h
#include "Base.h"
class BaseFactory
{
public:
BaseFactory(const string &sClassName){msClassName = sClassName;};
Base * Create()
{
if(msClassName == "DerivedA")
{
return new DerivedA();
}
else if(msClassName == "DerivedB")
{
return new DerivedB();
}
else if(/*etc...*/)
{
/*etc...*/
}
};
private:
string msClassName;
};
/*etc.*/
Gibt es eine Möglichkeit, irgendwie wandelt diese Zeichenfolge in eine tatsächliche Typ (Klasse), so dass BaseFactory nicht haben, zu wissen, alle möglichen Abgeleiteten Klassen, und haben, wenn() für jedes von Ihnen? Kann ich produzieren eine Klasse von dieser Schnur?
Ich denke, das kann man in C# durch Reflexion. Gibt es etwas ähnliches in C++?
Kommentar zu dem Problem
seine teilweise möglich mit C++0x und variadic templates..
InformationsquelleAutor der Frage Gal Goldman | 2009-02-24
Du musst angemeldet sein, um einen Kommentar abzugeben.
NÖ, es gibt keine, es sei denn, Sie tun das mapping selbst. C++ hat keinen Mechanismus, um Objekte zu erstellen, deren Typen werden zur Laufzeit ermittelt. Sie können mit einer Karte zu tun, die Zuordnung jedoch selbst:
Dann kann man
Immer eine neue Instanz. Eine weitere Idee ist, dass die Typen registrieren Sie sich:
Könnten Sie sich entscheiden, erstellen Sie ein makro für die Registrierung
Ich bin sicher, es gibt bessere Namen für die zwei, obwohl. Eine andere Sache, die Sinn macht zu nutzen, hier ist
shared_ptr
.Wenn Sie eine Reihe von nicht verwandten Arten, die keine gemeinsame Basis-Klasse haben, können Sie die Funktion Zeiger als return-type der
boost::variant<A, B, C, D, ...>
statt. Wie, wenn Sie eine Klasse Foo, Bar und Baz, sieht es wie folgt aus:Einen
boost::variant
ist wie eine union. Er weiß, welcher Typ ist in ihm gespeichert sind, indem Sie suchen, was Objekt wurde initialisiert oder zugewiesen. Ein Blick in die Dokumentation hier. Schließlich ist die Verwendung des raw-Funktion-Zeiger ist auch ein bisschen ältlich. Moderne C++ - code sollte abgekoppelt von bestimmten Funktionen /Arten. Möchten Sie vielleicht einen Blick inBoost.Funktion
suchen nach einem besseren Weg. Es würde dann so Aussehen (der Karte):std::function
verfügbar sein wird in der nächsten version von C++ zu, einschließlichstd::shared_ptr
.InformationsquelleAutor der Antwort Johannes Schaub - litb
Nein gibt es nicht. Meine bevorzugte Lösung für dieses problem ist um ein Wörterbuch zu erstellen, welche Karten Namen der Schöpfung-Methode. Klassen, die erstellt werden soll, wie diese registrieren Sie dann eine Methode zum erzeugen des mit dem Wörterbuch. Dies wird diskutiert im detail in der GoF Pattern-Buch.
InformationsquelleAutor der Antwort
Die kurze Antwort ist, können Sie nicht. Siehe diesen Fragen warum:
InformationsquelleAutor der Antwort Michael Kristofik
Habe ich beantwortet, in einem anderen, SO dass die Frage über C++ - Fabriken. Bitte sehen dort, wenn eine flexible Fabrik ist von Interesse. Ich versuche, zu beschreiben, einen alten Weg, von ET++ zur Verwendung von Makros gearbeitet hat ideal für mich.
ET++ war ein Projekt zum alten Hafen MacApp zu C++ und X11. In die Bemühungen von it-Eric Gamma etc angefangen, zu überlegen Design Patterns
InformationsquelleAutor der Antwort epatel
boost::funktional hat ein Werk die Vorlage, die ist Recht flexibel: http://www.boost.org/doc/libs/1_54_0/libs/functional/factory/doc/html/index.html
Meine Vorliebe allerdings ist das generieren von wrapper-Klassen, die das verbergen der mapping-und Objekt-Erstellung Mechanismus. Die häufigste Szenario, das ich begegnen, ist die Notwendigkeit für die Kartierung von verschiedenen abgeleiteten Klassen einige Basis-Klasse zu Tasten, wo die abgeleiteten Klassen haben alle einen gemeinsamen Konstruktor-Signatur zur Verfügung. Hier ist die Lösung, die ich mir ausgedacht habe, so weit.
Ich bin generell gegen schwere makro verwenden, aber ich habe eine Ausnahme hier. Der obige code erzeugt GENERIC_FACTORY_MAX_ARITY + 1 Versionen einer Klasse namens GenericFactory_N, für jedes N zwischen 0 und GENERIC_FACTORY_MAX_ARITY inclusive.
Verwendung der generierten Klassen-templates ist sehr einfach. Angenommen, Sie möchten eine factory zum erstellen von BaseClass abgeleitet Objekte mit einem string-mapping. Jede der abgeleiteten Objekte 3 Ganzzahlen als Konstruktor-Parameter.
Den GenericFactory_N Klasse Destruktor virtuell ist, dass die folgenden.
Beachten Sie, dass diese Zeile die generische Fabrik-generator makro -
Übernimmt die generische Fabrik-header-Datei hat den Namen GenericFactory.hpp
InformationsquelleAutor der Antwort texta83
Bedeutung der Reflexion als in Java.
es gibt einige Infos hier:
http://msdn.microsoft.com/en-us/library/y0114hz2(VS.80).aspx
Generell, Suche auf google nach "c++ - Reflexion"
InformationsquelleAutor der Antwort Ido Weinstein
InformationsquelleAutor der Antwort user3458845
Dies ist das factory-pattern. Siehe wikipedia (und diese Beispiel). Sie können nicht erstellen, eine Art per se aus einem string ohne einige schlimme hack. Warum brauchen Sie diese?
InformationsquelleAutor der Antwort dirkgently
Tor Brede Vekterli bietet eine boost-Erweiterung, die bietet genau die Funktionalität, die Sie suchen. Derzeit ist es etwas umständlich, Bestückung mit Strom-boost-libs, aber ich war in der Lage, um es arbeiten mit 1.48_0 nach der änderung seiner Basis-namespace.
http://arcticinteractive.com/static/boost/libs/factory/doc/html/factory/factory.html#factory.factory.reference
In Antwort auf diejenigen, die Frage, warum so ein Ding (als Reflexion) wäre nützlich für c++ - ich benutze es für die Interaktion zwischen der Benutzeroberfläche und dem ein-Motor - der Benutzer wählt eine option in der Benutzeroberfläche, und der Motor nimmt das UI-Auswahl-string, und erzeugt ein Objekt des gewünschten Typs.
Der Hauptvorteil der mit dem Rahmen hier (über die Aufrechterhaltung einer Frucht-die Liste irgendwo) ist, dass die Registrierung der Funktion ist in jeder Klasse die definition (und benötigt nur eine Zeile code aufrufen der Registrierung eingetragene Funktion pro Klasse) - im Gegensatz zu einer Datei mit der Frucht-Liste, die müssen manuell Hinzugefügt werden, jedes mal, wenn eine neue Klasse abgeleitet ist.
Ich habe die Fabrik eine statische member-meine base-Klasse.
InformationsquelleAutor der Antwort DAmann