delete mit zeiger anderen types?



  • vlad_tepesch schrieb:

    das ist totaler blödsinn und wird nicht funktionieren.
    nur mit der Größe kann man keine Objekte erzeugen.

    deswegen frag ich ja wie das anders gemacht werden kann.

    factorys sind natürlich möglich, nur sehr aufwändig. wenn ich
    jeden typ, int, float, structs (jede verschiedene struct)registrieren müsste,
    dann gute nacht. user-defined klassen müssen per factory erzeugt werden, aber
    bei PODs sollte das doch zu vermeiden sein?!

    die bisherige lösung besteht wie bereits gesgt aus einem exteren speicher.
    damit kann ich immer dieselbe POD-verwaltungsklasse einsetzen.


  • Mod

    helferlein schrieb:

    aber bei PODs sollte das doch zu vermeiden sein?!

    Kommt darauf an, was du dir vorstellst. Wie willst z.B. einen 32bit-integer von einem 32bit-float unterscheiden?



  • überhaupt nicht.

    class test
    {
    public:
        float f;
        int i;
    };
    
    // ...serialisieren
    
    test *t = dynamic_cast<test *>(Deserialise(stream)); // dyn_cast nur als beispiel
    

    da es klassenfactorys gibt, muss ich nur dafür sorgen, dass die daten am richtigen
    platz sind. nach der deserialisierung kann ich die erstellte klasse ganz normal
    verwenden.



  • Wie behandelst Du einen std::string?



  • das ganze ist zum scheitern verurteilt.
    Wie schon gesagt wurde:
    die serialisierung des Speichers eines gesammten Objektes macht keinen Sinn.
    Ein mal neu kompilieren mit wenigen Änderungen und du kannst alle alten dateien wegschmeißen.
    Ganz zu schweigen von einer Compileränderung.

    bei deiner Methode die Daten aus dem Stream zu holen: woher weißt du wie groß das objekt ist?
    Was machst du mit T, die nicht nur Kompositionen aus Elementardatentypen sind und zB selbst speicher anfordern?



  • vlad_tepesch schrieb:

    Ein mal neu kompilieren mit wenigen Änderungen und du kannst alle alten dateien wegschmeißen.
    Ganz zu schweigen von einer Compileränderung.

    natürlich. aber sobald die serialisierung fertig ist, muss sie nicht mehr geändert
    werden. der rest kann sich ruhig ändern.

    die größe wird im stream mitgespeichert.
    einen std::string sowie bestimmte typen bekommen eine eigene behandlung.



  • helferlein schrieb:

    einen std::string sowie bestimmte typen bekommen eine eigene behandlung.

    Und damit auch alle Typen, die einen std::string enthalten oder einen std::vector oder einen Typ mit Pimpl-Idiom. Mhhm. Nun wird auch nachträglich gepimlt.



  • volkard schrieb:

    Und damit auch alle Typen, die einen std::string enthalten oder einen std::vector oder einen Typ mit Pimpl-Idiom.

    eben nicht.

    jedes objekt serialisiert nur seine kinder, und auch nur die, die von einer
    gewissen klasse erben. das ganze lässt sich bis auf PODs runterbringen.

    z.b.

    class test : public Streamable
    {
    public:
        test() : integer(this), name(this) // registrieren
        {
            integer = 5;
            name = "hallo";
        }
    
        StreamablePOD<int> integer;
        StreamablePOD<std::string> name; // std::string bekommt ne extrawurst (spezialisierung)
    };
    
    Streamable::RegisterClass(Allocator<test>());
    Stream s;
    
    test t;
    t.Serialize(s);
    
    test *pt = dynamic_cast<test *>(s.Deserialize());
    
    assert(pt->integer == 5);
    

    soweit funtzt es schon. stream rein und klasse raus.

    ist darauf spezialisiert, eine komplette klassenhierachie mit all ihren
    verweisen, etc... laden zu können.

    vector, string und die ganzen std::*'s bekommen ne eigene spezialisierung.



  • helferlein schrieb:

    StreamablePOD<std::string> name; // std::string bekommt ne extrawurst
    

    Ah! Da hast Du also geschummelt. Ja, diesen Schummel mag ich.
    Der führt mich zu

    class test:public SomeBase
    {
    public:
        test()
        :integer(5)
        ,name(hallo)
        {
        }
        test(istream& in): SomeBase(in), integer(in), name(in)
        {
        }
        void save(ofstream& out)
        {
           SomeBase::save(out);
           integer.save(out);
           name.save(out);
        }
    private:
        StreamablePOD<int> integer;
        StreamablePOD<std::string> name;
    };
    REGISTERSTREAMABLE(test,SomeBase);
    

    Der Leser macht dann

    while(in>>name)
       ziel.push_back(macher[name].machEinen(in));
    

    Der Schreiber macht

    for each i in quelle
       datei<<i->getName()<<' ';
       i->save(datei);
    

    oder so.



  • volkard schrieb:

    Ah! Da hast Du also geschummelt. Ja, diesen Schummel mag ich.

    😃 😃 😃

    es wird sogar noch lustiger:

    da jede POD-klasse innerhalb der oberklasse ist, muss ich nur "save"
    für die oberste klasse aufrufen. der rest geht automatisch 🙂

    (innerhalb heißt. this < POD < this + 1)


Anmelden zum Antworten