To brudna hack, ale można zniszczyć i odbudować siebie:
MyItemT&
MyItemT::operator=(const MyItemT& other)
{
if (this == &other) return *this; // "suggested" by Herb Sutter ;v)
this->MyItemT::~MyItemT();
try {
new(this) MyItemT(other);
} catch (...) {
new(this) MyItemT(); // nothrow
throw;
}
return *this;
}
Edit: bym zniszczyć moją wiarygodność, ja nie faktycznie to zrobić sam, chciałbym usunąć const
. Jednak debatowałem nad zmianą praktyki, ponieważ jest ona użyteczna i lepsza w użyciu, gdy tylko jest to możliwe.
Czasami istnieje rozróżnienie między zasobem a wartością reprezentowaną przez obiekt. Członek może być uzależniony od zmian wartości, o ile zasób jest taki sam i byłoby miło, gdybyśmy mieli na to czas.
Edit 2: @Charles Bailey dostarczył tę wspaniałą (i wysoce krytyczną) link: http://gotw.ca/gotw/023.htm.
- Semantyka jest trudna w dowolnej klasie pochodnej
operator=
.
- Może być nieefektywna, ponieważ nie wywołuje zdefiniowanych operatorów przypisania.
- Jest to niezgodne z wonky
operator&
przeciążeń (cokolwiek)
- itp
Edit 3: Myśląc przez "który zasób" vs "Jaką wartość" różnicy, wydaje się jasne, że operator=
powinien zawsze zmiany wartość, a nie zasób. Identyfikator zasobu może wtedy być const
. W tym przykładzie wszyscy członkowie to const
. Jeśli "informacja" jest tym, co jest przechowywane w "pakiecie", to może pakiet powinien być const
, a informacje nie.
Problem polega więc na tym, że nie rozumiemy semantyki przypisania jako oczywistej wartości w tym przykładzie, jeśli "informacje" są w rzeczywistości metadanymi. Jeśli jakakolwiek klasa posiada numer MyItemT
, chce go przełączać z jednego pakietu na inny, musi albo zrezygnować i użyć zamiast tego auto_ptr<MyItemT>
, albo użyć podobnego hacka, jak wyżej (test tożsamości jest niepotrzebny, ale pozostało tylko catch
) zaimplementowanego jako z poza.Ale operator=
nie powinien zmieniać powiązania zasobów, z wyjątkiem wyjątkowej funkcji, która absolutnie nie będzie kolidować z niczym innym.
Należy pamiętać, że ta konwencja jest zgodna z poradą Sutter dotyczącą wdrażania konstrukcji kopii pod względem przydziału.
Jeśli twoja klasa jest przypisywalna i tych członków można zmienić, zabrać "const". To po prostu nie ma sensu. – GManNickG
@GMan - Myślę, że masz rację. Szukałem pewnego rodzaju podejścia podobnego do znajomego, które pozwala operatorowi '' mieć specjalne uprawnienia, które nadal uniemożliwiają ręczne zastępowanie członków. Ale po przeczytaniu tego, co powiedział @MichaelMrozek, nie jest to wcale bezpieczne. – LeopardSkinPillBoxHat