Ich frage mich, welche möglichen Vorteile Copy-on-Write hat. Natürlich erwarte ich keine persönlichen Meinungen, sondern reale praktische Szenarien, in denen dies auf greifbare Weise technisch und praktisch von Vorteil sein kann. Und mit greifbar meine ich etwas mehr, als Ihnen das Schreiben eines &
Zeichens zu ersparen .
Zur Verdeutlichung steht diese Frage im Zusammenhang mit Datentypen, bei denen durch Zuweisung oder Kopierkonstruktion eine implizite flache Kopie erstellt wird. Durch Änderungen wird jedoch eine implizite tiefe Kopie erstellt, und die Änderungen werden anstelle des ursprünglichen Objekts darauf angewendet.
Der Grund, den ich frage, ist, dass ich anscheinend keine Vorteile darin finde, COW als implizites Standardverhalten zu haben. Ich verwende Qt, das COW für viele Datentypen implementiert hat, praktisch alle, denen dynamisch zugeordneter Speicher zugrunde liegt. Aber wie kommt es dem Benutzer wirklich zugute?
Ein Beispiel:
QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource
qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
// s is still "some text"
Was gewinnen wir mit COW in diesem Beispiel?
Wenn wir nur const-Operationen verwenden wollen, s1
ist dies redundant und kann genauso gut verwendet werden s
.
Wenn wir beabsichtigen, den Wert zu ändern, verzögert COW die Ressourcenkopie nur bis zur ersten nicht konstanten Operation, und zwar auf (wenn auch minimale) Kosten für die Erhöhung der Ref-Anzahl für die implizite Freigabe und das Trennen vom gemeinsam genutzten Speicher. Es sieht so aus, als ob der gesamte Aufwand für COW sinnlos ist.
Im Kontext der Parameterübergabe ist dies nicht viel anders. Wenn Sie den Wert nicht ändern möchten, übergeben Sie ihn als const-Referenz. Wenn Sie ihn ändern möchten, erstellen Sie entweder eine implizite tiefe Kopie, wenn Sie ihn nicht ändern möchten das ursprüngliche Objekt oder übergeben Sie es als Referenz, wenn Sie es ändern möchten. Wiederum scheint COW unnötiger Overhead zu sein, der nichts bewirkt, und fügt nur eine Einschränkung hinzu, dass Sie den ursprünglichen Wert nicht ändern können, selbst wenn Sie möchten, da sich jede Änderung vom ursprünglichen Objekt löst.
Je nachdem, ob Sie über COW Bescheid wissen oder sich dessen nicht bewusst sind, kann dies entweder zu Code mit unklarer Absicht und unnötigem Overhead führen oder zu einem völlig verwirrenden Verhalten, das nicht den Erwartungen entspricht und Sie am Kopf kratzen lässt.
Mir scheint, dass es effizientere und lesbarere Lösungen gibt, unabhängig davon, ob Sie eine unnötig tiefe Kopie vermeiden möchten oder eine erstellen möchten. Wo liegt also der praktische Nutzen von COW? Ich gehe davon aus, dass es einen gewissen Nutzen geben muss, da es in einem so populären und mächtigen Rahmen verwendet wird.
Darüber hinaus ist COW nach dem, was ich gelesen habe, jetzt in der C ++ - Standardbibliothek ausdrücklich verboten. Ich weiß nicht, ob die Nachteile, die ich darin sehe, etwas damit zu tun haben, aber so oder so muss es einen Grund dafür geben.
[]
Operator verwenden. COW ermöglicht also schlechtes Design - das klingt nicht nach einem großen Vorteil :) Der Punkt im letzten Absatz scheint gültig zu sein, aber ich selbst bin kein großer Fan impliziten Verhaltens - die Leute halten es für selbstverständlich und haben es dann Es ist schwierig herauszufinden, warum Code nicht wie erwartet funktioniert, und sich immer wieder zu fragen, bis sie herausgefunden haben, was sich hinter dem impliziten Verhalten verbirgt.