IMPLEMENT_SERIAL und Kein Standardkonstruktor verfügbar



  • Dann Erzeuge doch ein Dummy Zwischenobjekt mit fiktiven Daten und setze die dann anschließend.

    Ok das wäre jetzt eine Lösung.

    Was ist daran kompliziert?

    Nein die Serialisierung ist nicht kompliziert.
    Kompliziert ist folgendes - für mich auf jeden Fall.

    Es sind mehrere Klassen von denen ich Objekte erzeugen will. Dies liese sich mit der Factory Method z.B. mit einem switch case lösen. Nun ist der Name der Klasse aber wie folgt aufgebaut. CNameNummer -> Beispiel: CMyClass1, CMyClass2, ...
    Nun würde ich ungerne ein switch case machen mit ca 50. cases.

    Nun suche ich natürlich eine Möglichkeit um anhand des Namens ein Objekt zu erstellen ohne switch case. Das ist für mich das komplizierte.


  • Mod

    Nun die MFC macht auch ncihts anderes. Es gibt eine Liste aller Klassen für die Serialisierug die durchsucht wird.

    Du könntest ein eigenes System aufbauen, bei denen jedes Objekt seine eigene Factory hat. Jedes Objekt initialisiert sich in dem es (über statische Member) seine Factory im System anmeldet (z.B. in eine Liste oder Map einträgt).

    Dann fragst Du das statische Factory Modul "Schau her ich habe hier eine Signatur, gehört es zu Dir, wenn ja erzeuge mal das Objekt aus den nachfolgenden Daten!". Das ganze macht man noch über eine map und es geht rasend schnell auch bei 1000 Elementen.

    Nichts anderes macht die MFC für dich.



  • Hallo.

    Danke für deine Hilfe. Bin noch nicht ganz durchgestiegen wie du das meinst, bzw. wie ich das realisieren soll. Vieleicht nochmal 10mal lesen 🙂

    Habe es jetzt erstmal so gemacht wie in deinem ersten Vorschlag. Mit IMPLEMENT_SERIAL und Dummy Daten.

    Wenn ich nun aber ein Objekt erzeugen will erhalte ich immer NULL. Wenn ich die Funktion CRuntimeClass::CreateObject debugge erscheint meine Klasse nicht in der Klassenliste.

    Was habe ich gemacht:

    1. Habe meine Klasse von CObject abgeleitet. CMyClass1 : public CObject
    2. Makro DECLARE_SERIAL(CMyClass1) in die Header
    3. Makro IMPLEMENT_SERIAL(CMyClass1,CObject,1) in die cpp
    4. in meiner Factoryklasse Aufruf:
    class = (CMyClass*)CRuntimeClass::CreateObject("CMyClass1");



  • Kann das vieleicht daran liegen, dass meine Klasse in einem Namespace liegt


  • Mod

    Möglich und wahrscheinlich.
    Debugge doch den MFC Code. Das ist doch nicht schwer.

    Das MFC CObject Modell unterstützt keine Namespaces! Die Namen der Klassen werden ohne Namespaces gespeichert.



  • Debugge doch den MFC Code. Das ist doch nicht schwer.

    Habe ich doch gemacht, habe ich doch auch geschrieben.

    Also bei CreateObject wird ja die Methode FromName aufgerufen. In dieser Methode wird die Liste pModuleState->m_classList mit einer For-Schleife durchgegangen. Und in dieser Liste befindet sich meine Klasse nicht.

    Also wird es besser sein deinen anderen Vorschlag in die Tat umzusetzen?


  • Mod

    Aber Du kannst doch sehen, welche Namen in der Liste sind!



  • Aber Du kannst doch sehen, welche Namen in der Liste sind!

    Ja kann ich. Aber meiner ist halt nicht dabei.


  • Mod

    Dann stimmt was mit Deinen Namen nicht.
    Das CRuntimeClass Objekt enthält den Namen und wird durch IMPLEMENT_SERIAL mit erzeugt.

    Dann besorge Dir doch mal von einem neuen Objekt die CRuntimeClass!



  • Dann besorge Dir doch mal von einem neuen Objekt die CRuntimeClass!

    ? Du meinst ich soll das ganze mit einer anderen Klasse testen?



  • Ok. Das hat funktioniert. Dann muss was mit meinem Namen nicht passen.



  • Ich versteh es nicht. Habe alles kontrolliert. Der Name den ich bei IMPLEMENT_SERIAL angegeben habe ist genau der meiner Klasse. Er erscheint aber nicht in der Liste.
    Das müsste doch sonst eigentlich schon eine Fehler beim Kompilieren geben oder nicht?



  • Hallo.

    Habe nun zwei fast identische Klassen genommen. Unterschied ist das die eine mehr Membervariablen hat und von der anderen noch weitere Klassen abgeleitet sind.

    Von der einen Klasse lassen sich dynamisch Objekt erzeugen, ist in der Klassenliste vorhanden. Von der anderen lassen sich keine Objekte erzeugen, ist nicht in der Klassenliste vorhanden.

    Woran kann das denn liegen?



  • Hallo Herr Richter.

    Darf ich nochmal was fragen:

    Du schreibst:

    Du könntest ein eigenes System aufbauen, bei denen jedes Objekt seine eigene Factory hat. Jedes Objekt initialisiert sich in dem es (über statische Member) seine Factory im System anmeldet (z.B. in eine Liste oder Map einträgt).

    Hier stellt sich die Frage: wie soll sich das Objekt mit seiner Factory im System anmelden wenn es das Objekt ja noch gar nicht gibt?


  • Mod

    Du erzeugst über ein statisches Factory Objekt eine Liste, die sich selbst durch einen Konstruktor aufbaut. Dasist genau das was auch die MFC macht.



  • Hallo.

    Versteh ich immer noch nicht. Meine Klassen haben nun alle ein statische Methode um sich selber zu kreieren. Diese Funktion soll nun in einer Liste angemeldet werden. Aber wer meldet dies an.

    Ich packe doch in eine map den Klassennamen und die zugehörgige Create-Funktion. Nun muss doch aber jemand den Klassennamen und die Funktion kennen. Und das ist doch nur die Klasse selber. Aber wie will die sich anmelden wenn es sie noch gar nicht gibt.



  • Noch ein Tipp?


  • Mod

    Bau eine verkette Liste.
    Erzeuge für jeden Konstruktor ein statisches Objekt, dass dafür sorgt sich mit der initialisierung in die Liste einzutragen mit ID und Konstruktorfunktion.
    Das geht automatisch!

    Oder Bau Dir simpel selbst einen Array aus "Klassen Token" und statischer Factory Funktion.
    Das muss etwas gepflegt werden...



  • Erzeuge für jeden Konstruktor ein statisches Objekt, dass dafür sorgt sich mit der initialisierung in die Liste einzutragen mit ID und Konstruktorfunktion.

    Dass muss dann ja aber auch immer gepfelgt werden. Ich würde gerne aber ein Makro schreiben, ähnlich dem IMPLEMENT_SERIAL von MFC.

    Dass mir die Createfunkion in der Klasse erstellt und sich gleichzeitig in eine Liste einträgt.



  • Das geht automatisch!
    

    Wie soll das gehen.

    Also wenn eine meiner Klasse so aussieht.

    class CMyClass1 : public CMyClass
    {
      CMyClass1(int var);
      ~CMyClass1();
    
       static CMyClass* CreateObject(int var)
       {
         return new CMyClass(var)
       }
    
    };
    
    std::map<CString,pFnCreate> classmap;
    

    Wie bekomme ich nun die Funktion CreateObject() und den Klassennamen CMyClass1 in die map? Wer ruf hier den insert auf?


Anmelden zum Antworten