Etwas stört mich über:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
Zuerst liest das Wort „swap“ wenn mein Geist „Kopie“ ärgert meinen gesunden Menschenverstand denkt. Außerdem hinterfrage ich das Ziel dieses ausgefallenen Tricks. Ja, alle Ausnahmen beim Erstellen der neuen (kopierten) Ressourcen sollten vor dem Swap erfolgen. Dies scheint ein sicherer Weg zu sein, um sicherzustellen, dass alle neuen Daten gefüllt sind, bevor sie in Betrieb gehen.
Das ist in Ordnung. Also, was ist mit Ausnahmen, die nach dem Swap passieren? (wenn die alten Ressourcen zerstört werden, wenn das temporäre Objekt den Gültigkeitsbereich verlässt) Aus der Perspektive des Benutzers der Zuweisung ist die Operation fehlgeschlagen, außer dies ist nicht der Fall. Es hat einen großen Nebeneffekt: Die Kopie ist tatsächlich passiert. Es war nur eine Ressourcenbereinigung, die fehlgeschlagen ist. Der Status des Zielobjekts wurde geändert, obwohl die Operation von außen als fehlgeschlagen erscheint.
So schlage ich vor, anstelle von „Swap“ einen natürlicheres „Transfer“ zu tun:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
transfer(tmp);
return *this;
}
Es ist immer noch der Bau des temporären Objekts, aber die nächsten sofortigen Maßnahmen ist es, alle aktuellen Ressourcen zu befreien das Ziel vor dem Verschieben (und NULL, so dass sie nicht doppelt freigegeben werden) die Ressourcen der Quelle zu ihm.
Anstelle von {construct, move, destruct} schlage ich {construct, destruct, move} vor. Der Zug, der die gefährlichste Aktion ist, ist der letzte, der nach der Regelung des Restes unternommen wurde.
Ja, Zerstörung Fehler ist ein Problem in jedem Schema. Die Daten sind entweder beschädigt (kopiert, wenn Sie nicht dachten, dass es war) oder verloren (befreit, wenn Sie nicht dachten, dass es war). Verloren ist besser als verdorben. Keine Daten sind besser als schlechte Daten.
Transfer statt Tausch. Das ist sowieso mein Vorschlag.
"... haben fast den gleichen Code ..."? Hmm ... Du musst etwas falsch machen. Versuchen Sie, die Notwendigkeit zu minimieren, benutzerdefinierte Funktionen dafür zu verwenden, und lassen Sie den Compiler die ganze schmutzige Arbeit erledigen. Dies bedeutet häufig, Ressourcen in einem eigenen Mitgliedsobjekt zu kapseln. Sie könnten uns Code zeigen. Vielleicht haben wir ein paar gute Designvorschläge. – sellibitze
Mögliches Duplikat von [Codevervielfältigung zwischen operator = und dem Kopierkonstruktor reduzieren] (http://stackoverflow.com/questions/1477145/reducing-code-duplication-between-operator-and-the-copy-constructor) – mpromonet