Coś przeszkadza mi o:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
pierwsze czytanie słowa „swap”, kiedy mój umysł jest myślenie „kopię” drażni mój zdrowy rozsądek. Ponadto podważam cel tej fantazyjnej sztuczki. Tak, wszelkie wyjątki w konstruowaniu nowych (kopiowanych) zasobów powinny się zdarzyć przed wymianą, co wydaje się bezpiecznym sposobem upewnienia się, że wszystkie nowe dane są wypełnione przed uruchomieniem.
W porządku. A co z wyjątkami, które nastąpią po wymianie? (gdy stare zasoby zostaną zniszczone, gdy tymczasowy obiekt znajdzie się poza zakresem) Z punktu widzenia użytkownika przypisania, operacja się nie powiodła, z wyjątkiem tego, że nie. Ma ogromny efekt uboczny: kopia rzeczywiście się wydarzyła. To tylko niektóre czyszczenia zasobów, które zawiodły. Stan obiektu docelowego został zmieniony, mimo że operacja wydawała się z zewnątrz nieudana.
Więc proponuję zamiast „swap” do zrobienia bardziej naturalny „Transfer”:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
transfer(tmp);
return *this;
}
Wciąż budowy tymczasowego obiektu, ale obok jest natychmiastowe działanie, aby uwolnić wszystkie aktualne zasoby miejsce docelowe przed przeniesieniem (i NULLing, aby nie zostały uwolnione podwójnie) zasobów źródła do niego.
Zamiast {konstruuj, przenoś, niszcz,} proponuję {konstruuj, niszcz, przesuwaj}. Ruch, który jest najniebezpieczniejszą czynnością, jest tym, który został zrobiony ostatni po tym, jak wszystko inne zostało ustalone.
Tak, niepowodzenie destrukcji jest problemem w obu systemach. Dane są uszkodzone (skopiowane, gdy nie sądzisz, że tak się stało) lub utracone (uwolnione, gdy nie myślałeś, że to było). Utracone jest lepsze niż uszkodzone. Żadne dane nie są lepsze niż złe dane.
Przelew zamiast zamiany. Taka jest moja sugestia.
"... mają prawie taki sam kod ..."? Hmm ... Musisz zrobić coś złego. Postaraj się zminimalizować potrzebę korzystania z funkcji zdefiniowanych przez użytkownika i pozwól, aby kompilator wykonał całą brudną robotę. Często oznacza to hermetyzowanie zasobów w ich własnym obiekcie członkowskim. Możesz pokazać nam jakiś kod. Może mamy jakieś dobre sugestie dotyczące projektu. – sellibitze
Możliwy duplikat [Zmniejszenie duplikacji kodu pomiędzy operatorem = a konstruktorem kopiującym] (http://stackoverflow.com/questions/1477145/reducing-code-code-duplication-between-operator-and-copy-constructor) – mpromonet