Copy-assignment for a class with a reference member variable is a no-no because you can't reassign the reference. But what about move-assignment? I tried simply move
ing it but, of course, that destroys the source object when I just want to move the reference itself:
class C { public: C(X& x) : x_(x) {} C(C&& other) : x_(std::move(other.x_)) {} C& operator=(C&& other) { x_ = std::move(other.x_); } private: X& x_; }; X y; C c1(y); X z; C c2(z); c2 = c1; // destroys y as well as z
Should I just not be implementing move-assignment and sticking with move-construction only? That makes swap(C&, C&)
hard to implement.
The move assignment operator is different than a move constructor because a move assignment operator is called on an existing object, while a move constructor is called on an object created by the operation. Thereafter, the other object's data is no longer valid.
Copy assignment operator create a new object from passed object by copying each and every item into a new memory location. Move assignment operator create a new object by using as much memory from passed object.
A move assignment is less, not more restrictively defined than ordinary assignment; where ordinary assignment must leave two copies of data at completion, move assignment is required to leave only one.
Move constructor moves the resources in the heap, i.e., unlike copy constructors which copy the data of the existing object and assigning it to the new object move constructor just makes the pointer of the declared object to point to the data of temporary object and nulls out the pointer of the temporary objects.
(Posted as an answer from comment as suggested by the OP)
In general if one wants to do non-trivial stuff with references in C++, one would be using reference_wrapper<T>
, which is essentially a fancy value-semantic stand-in for a T&
, then one would be done with it - it already provides (re)assignment and other operations. I'm sure that would make move constructor and assignment near-trivial, if not trivial (note not trivial
as in per the is_trivially_*
semantics).
"Reference wrapper" is added to C++03 as part of TR1, and is part of C++11.
Documentation: http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With