Memento mit Originator drumherum oder für sich?



  • Wenn ich aber eine freie Funktion habe, die Object zurückgibt, dann würde er ohne NRVO kopieren. Wenn Object nicht copyable ist, geht das aber nicht, also "müsste" ich das temporär erstellte Objekt moven, was natürlich nicht geht.

    Das sind doch alles nur Randueberlegungen. premature

    Memento ist nur eine etwas eigene Form der Serialisierung. Hier wird eben keine datei oder aehnliches benutzt sondern ein Objekt.



  • Da ich es jetzt eh mit Originator == Object umsetze, ist es auch einfach egal.

    Wenn ich es aber mit freier Funktion machen würde, warum wäre es dann premature? Du meinst, ich sollte einfach:

    Object create(const Memento& m)
    {
        Object obj(/* ... */);
        // tu was
        return obj;
    }
    

    schreiben und hoffen, dass der Compiler das schon von selbst moved?

    Ist halt blöd, wenn mein Compiler das zufällig macht, ein anderer aber nicht, darum wollte ich das vorher diskutiert haben, um nicht compilerabhängigen Code zu schreiben. 🙂



  • schreiben und hoffen, dass der Compiler das schon von selbst moved?

    Das ist erstmal NRVO. Und wenn du Object obj = std::move(create(...)) machst, dann sollte der move-Konstruktor aufgerufen werden.

    Ich verstehe nicht, warum create/restore eine freie Funktion sein soll. Und da es hauptsaechlich um das zuruecksetzen in einen vorherigen Zustand geht, sollte die Klasse es explizit im Interface formulieren. Aehnlich wie bei Serialisierung, nur die Klasse Weiss, wie Objekte de-/serialisiert werden koennen.



  • Ahhhh, natürlich. Alles klar, dankeschön 👍

    Und wie gesagt, das mit der freien Funktion war falsch von mir gedacht, weil mein Gedankengang war: Man braucht Originator mit Originator != Object (das war falsch) und da ich Originator dann aber nicht als Klasse, sondern eher namespace sah, wurden die restore/create-Funktionen automatisch zu freien Funktionen.

    War Käse, werden jetzt Methoden von Object, wie Du ja vorgeschlagen hast. 🙂



  • Und wenn du Object obj = std::move(create(...)) machst, dann sollte der move-Konstruktor aufgerufen werden.

    Da braucht es kein move . Solange create(...) ein rvalue ist (was bei obiger Definition der Fall ist), dann wird automatisch der Move-Konstruktor gewählt.



  • Sone:
    Gut zu wissen, danke für die Ergänzung!



  • Ich habe das Eingangsposting nur flüchtig gelesen. Wenn's aber um Versionierung und/oder Undo/Redo geht, sollte man sich vielleicht mal überlegen, ob einem Copy-on-Write helfen könnte. Dann würde man einfach die alte Version behalten, kopieren und die Kopie ändern. Per COW und geschickten Baum-artigek Strukturen könnte man viel Redundanz einsparen. Sean Parent, einer von Adobe, hatte dazu mal einen Vortrag gemacht. So haben die in ihrer neuen Photoshop-Version das Undo/Redo-System gemacht. Sei wohl alles weniger fehleranfällig und leichter durchschaubar als das, was sie vorher hatten.



  • Es geht in der Tat um Undo/Redo und zwar von baumartigen Strukturen.

    Für jetzt reicht zwar mein einfaches System (auch wenn es durch Kopien langsam für riesige Datenmengen ist, die zum Glück aber eh nicht praktikabel sind), aber besser ist immer gut.

    Auf die (sehr) Schnelle hat mein googlen nichts ergeben. Hast Du rasch einen Link oder das richtige Stichwort parat? Falls das in eine Suche Deinerseits ausarten würde, mache ich das natürlich selbst.



  • Einer von den aktuellen Going Native 2013 Videos.

    Und wenn es um Baumstrukturen geht, sind http://en.wikipedia.org/wiki/Persistent_data_structure ganz gut.



  • Der Vortrag, den ichmeinte, ist älter:

    http://isocpp.org/blog/2012/12/value-semantics-and-concepts-based-polymorphism-sean-parent

    Leider ist die Qualität des Videos nicht so dolle.

    In seinen neueren Going Native 2013 Talks gibt es Parallelen, die haben aber weniger was mit Undo/Redo zu tun.



  • Habe mir den Vortrag durchgeschaut, das undo/redo ist da aber nur ein Nebenresultat, finde ich. Das ist zwar cool, aber zentral ist ja das Nutzen von Baumstrukturen, auf deren Elemente man Operationen anwenden kann, die nur für den notwendigen Fall polymorph sind. (hm, aber die Zusammenfassung erscheint mir nicht so passend; value-semantics aber auch nicht) Die Idee, dass Polymorphie nur Implementierungsdetail ist und nicht den Client-Code verkomplizieren soll, finde ich am spannendsten (das wurde hier ja auch bereits von einigen angemerkt, erscheint mir aber noch eine wenig durchgesetzte Idee).

    Auf alle Fälle interessante Ideen drin. 🙂

    Leider sind meine Baumstrukturen relativ komplex, sodass es eigentlich Sinn ergeben würde, dass ich nur die Änderungen speichere. Aber es reicht von der Performance gerade noch aus.

    knivil:
    Danke auch dafür, da schaue ich dann als nächstes rein. 😋


Anmelden zum Antworten