Klasse nur durch Namen erzeugen



  • Hallo,

    ich habe wirklich schon die FAQ und die Suche bemüht, aber wohl die falschen Stichworte benutzt weil ich zu diesem "Standardthema" nichts finden konnte: RTTI und so weiter 🙂

    Meine Frage lautet jedenfalls:

    Wie kann ich ein Objekt erzeugen, wenn ich nur den Namen der Klasse als String verfügbar habe?



  • Mithilfe des Factory-Patterns. Ohne das gehts nicht.

    /edit Klasse != Objekt! Der Threadname ist irreführend.



  • Ist nicht möglich, du kannst dir höchstens ne Funktion schreiben, welche nen String nimmt und das Objekt dann erzeugt.



  • Noch ein Stichwort für weitere Suchen: "virtueller Konstruktor"



  • Tut mir leid das ich mich missverständlich ausgedrückt habe. Bin halt noch ein Anfänger in Sachen Programmierung 🙂

    Mein konkretes Problem sieht so aus:
    Ich lese aus einer Textdatei bestimmt Klassennamen und will diese dann instantieren. Bislang habe ich eine große IF-ELSE-Kaskadierung die sehr unhübsch ist. Auch wenn eine neue Klasse hinzukommt, muß der IF-ELSE-Baum angepasst werden.

    Wenn ich die Fabrikmethode verwenden würde, dann hätte ich wieder den gleichen Anpassungsaufwand bei jeder neuen Klasse die hinzukommt.

    Meine Vorstellung wäre etwa so:

    try
    {
     Object o = new "Derived1";
    } catch...
    

    Wenn die Klasse nicht vorhanden ist, wird das durch den Catch gefangen.
    Wäre eventuell eine Überladung des new-Operators der richtige Ansatzpunkt?

    Vielleicht geht das aber in C++ auch gar nicht 🙂



  • lizardking schrieb:

    Vielleicht geht das aber in C++ auch gar nicht 🙂

    Das haben die obigen Beiträge versucht Dir zu sagen, ja 😉



  • Nein, in C++ geht das so definitiv nicht (zumal zur Laufzeit die Klassennamen gar nicht mehr existieren)- da bleibt als beste Alternative wirklich nur eine Factory-Methode (notfalls kannst du ja eine map anlegen, in der jede abgeleitete Klasse sich mit Name und Create-Methode anmeldet:

    class BaseClass
    {
    public:
      static BaseClass* Create() {return NULL;}
    }
    typedef map<string,BaseClass* (*)()>Create_Map;
    Create_Map Creators;
    class Derived1 : public BaseClass
    {
      Derived1() { /* init */ };
    public:
      static BaseClass* Create() {return new Derived1;}
      static void register() {Creators["Derived1"]=&Create();
    }
    
    BaseClass* CreateByName(const string& name)
    {
      Create_Map::iterator pos=Creators.find(name);
      if(pos!=Creators.end())
        return pos->second();
      else
        //Fehlerbehandlung (throw, return NULL, o.ä.)
    }
    


  • Bitte einfach mal in die LOKI C++ Library schauen, da ist alles schon fertig. Muß man nur benutzen.


Anmelden zum Antworten