Operator przydziałów z członkami referencyjnymi
Czy jest to prawidłowy sposób tworzenia operatora przypisania z członkami, które są referencjami?
#include <new>
struct A
{
int &ref;
A(int &Ref) : ref(Ref) { }
A(const A &second) : ref(second.ref) { }
A &operator =(const A &second)
{
if(this == &second)
return *this;
this->~A();
new(this) A(second);
return *this;
}
}
Wydaje się kompilować i działać dobrze, ale z C++ tendencja do powierzchni niezdefiniowanego zachowania, gdy najmniej oczekiwane, i wszystkich ludzi, którzy mówią, że to niemożliwe, myślę, że jest pewne gotcha brakowało. Coś mnie ominęło?
4 answers
Jest poprawna składniowo. Jeśli umieszczenie nowych rzuca, jednak, można kończy się z obiektem, którego nie można zniszczyć. Nie wspominając o katastrofie jeśli ktoś pochodzi z twojej klasy. Po prostu tego nie rób.
Rozwiązanie jest proste: jeśli klasa musi obsługiwać przypisanie, nie użyj dowolnych członków odniesienia. Mam wiele zajęć, które odnoszą się argumenty, ale przechowuj je jako wskaźniki, tak aby Klasa mogła obsługiwać zadanie. Coś w stylu:
struct A
{
int* myRef;
A( int& ref ) : myRef( &ref ) {}
// ...
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-26 17:14:20
Innym rozwiązaniem jest użycie klasy reference_wrapper (w nagłówku funkcyjnym):
struct A
{
A(int& a) : a_(a) {}
A(const A& a) : a_(a.a_) {}
A& operator=(const A& a)
{
a_ = a.a_;
return *this;
}
void inc() const
{
++a_;
}
std::reference_wrapper<int>a_;
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-15 11:29:58
To, co robisz, jest technicznie poprawne, o ile wiem, ale generuje kłopoty. Na przykład, rozważmy, co dzieje się z klasą pochodną z A
, ponieważ jej operator przypisania generuje nowy obiekt (slicing). Nie możesz po prostu zmienić referencji W wskaźnik w swojej klasie?
Poza tym konstruktory kopiujące i operatory przypisania zwykle przyjmują argument przez const&
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-26 17:00:08
To co robisz jest poprawne, ale nie jest to bardzo bezpieczny sposób pisania operatora przypisania kopii. Należy również rozważyć użycie elementu wskaźnikowego, a nie elementu referencyjnego.
Powinieneś zaimplementować go używając idiom Copy and Swap. Ma co najmniej 3 zalety w stosunku do Twojej implementacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:06:48