Frage

Wenn ich eine Basisklasse haben:

class Base 
{
public:
virtual void Test()=0;
};

und in einem dynamisch geladenen Modul (.so / DLL), implementiert I eine Klasse von diesem abgeleitet:

class SomethingFromBase : Base 
{
...
};

und der Benutzer, sobald diese Bibliothek geladen wird, fragt eine Instanz von SomethingFromBase zu erstellen (lassen Sie uns sagen, dass wir den Namen von cin bekommen.), Und haben wir keine Kenntnis von SomethingFromBase (dh keine Möglichkeit, nur tun if(inputstr == "SomethingFrombase") { ... } ist es eine Möglichkeit, eine Instanz von SomethingFromBase?

zu erstellen

Ich bin ziemlich sicher, das ist unmöglich in (Standard) C ++, aber ich bin der Hoffnung, immer so wird mich überraschen!

Wenn diese mit dem Zusatz von etwas Bibliothek möglich ist, würde ich gerne noch darüber wissen. Dank!

Edit: Siehe cdhowie Antwort. Guides zur Umsetzung dieser Technik: http://www.linuxjournal.com/article/3687?page=0,1 http://www.abstraction.net/ViewArticle.aspx?articleID=67

War es hilfreich?

Lösung

Sie erreichen dies typischerweise durch erforderlich, dass Plug-Bibliotheken definieren eine globale Variable eines Strukturtyps, die Zeiger auf verschiedene Funktionen enthält, die Sie anrufen können. (Wie Setup, Teardown, etc.) Während der Setup-Funktion, würden sie in die Anwendung zurückrufen, um einige „Register“ Funktion, wo sie in einem String übergeben könnte den Namen der Klasse darstellt, und eine Fabrik Funktionszeiger, der ein schaffen Beispiel wenn sie ausgeführt werden.

Sie bunkern diese weg in irgendeiner Karte, und wenn der Benutzer eine Zeichenfolge eingibt, schauen Sie auf der Karte zu sehen, ob es eine Fabrik-Funktion registriert ist. Wenn ja, nur es nennen.

So nicht „true“ Reflexion ist, aber Sie können es manuell bis zu einem gewissen Grad hacken. Siehe zum Beispiel, Pidgin, die die Spezifikation von Protokoll-Plugins ermöglicht es, dass viele Einträge in der Protokollliste liefern kann.

EDIT: Hier ist eine nette Führung um etwas ähnliches zu implementieren. Ich bin eher eine C Person, so dass ich nicht für es wirklich genial oder irgendetwas zu sein, aber auf dem ersten Blick bürgen kann es sieht gut aus. Ich habe auf Linux in C ähnliche Sachen gemacht, und der grundlegende Ansatz funktioniert recht gut.

Andere Tipps

Haben Sie eine Karte speichert die Objekte der Klasse, von dem Klassennamen eingegeben. Alle Klassen, die müssen auf diese Weise erstellt werden, müssen von einer Basisklasse mit dem Namen etwas wie „Creatable“ abgeleitet werden Der Code das Objekt der Klasse hinzufügen muß mit der Umsetzung der Klasse gegeben werden.

//Creatable.h
#define IMPLEMENT_CREATABLE( ClassName ) \
  ObjectMap::Instance().Add( string(ClassName), new ClassName );

//ObjectMap.h. This is a singleton
class ObjectMap
{
  ...........
  map<string, Creatable *> myMap;
  ...........
public:
  void Add( const string &className, Creatable * );
  Creatable * Get( const string &className );
};

//My Class.h
class MyClass : public Creatable
{
  ................
};

//My Class.cpp
IMPLEMENT_CREATABLE(MyClass);


//Client.cpp
string className;
cin>>className;
Creatable *anObject = ObjectMap::Instance().Get( className );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top