In the C++ programming language, the assignment operator, '=', is the operator used for assignment. Like most other operators in C++, it can be overloaded.
The copy assignment operator, often just called the "assignment operator", is a special case of assignment operator where the source (right-hand side) and destination (left-hand side) are of the same class type. It is one of the special member functions, which means that a default version of it is generated automatically by the compiler if the programmer does not declare one. The default version performs a memberwise copy, where each member is copied by its own copy assignment operator (which may also be programmer-declared or compiler-generated).
The copy assignment operator differs from the copy constructor in that it must clean up the data members of the assignment's target (and correctly handle self-assignment) whereas the copy constructor assigns values to uninitialized data members.[1] For example:
My_Array first; // initialization by default constructor My_Array second(first); // initialization by copy constructor My_Array third = first; // Also initialization by copy constructor second = third; // assignment by copy assignment operator
Contents |
When deep copies of objects have to be made, exception safety should be taken into consideration. One way to achieve this when resource deallocation never fails is:
class My_Array { int * array; int count; public: My_Array & operator= (const My_Array & other) { if (this != &other) // protect against invalid self-assignment { // 1: allocate new memory and copy the elements int * new_array = new int[other.count]; std::copy(other.array, other.array + other.count, new_array); // 2: deallocate old memory delete [] array; // 3: assign the new memory to the object array = new_array; count = other.count; } // by convention, always return *this return *this; } // ... };
However, if a no-fail (no-throw) swap function is available for all the member subobjects and the class provides a copy constructor and destructor (which it should do according to the rule of three), the most straightforward way to implement copy assignment is as follows [2]:
public: void swap(My_Array & other) // the swap member function (should never fail!) { // swap all the members (and base subobject, if applicable) with other std::swap(array, other.array); std::swap(count, other.count); } My_Array & operator = (My_Array other) // note: argument passed by value! { // swap this with other swap(other); // by convention, always return *this return *this; // other is destroyed, releasing the memory }
The reason why operator = returns My_Array&
instead of void
is to allow chained assignments like the following:
array_1 = array_2 = array_3; // array_3 is assigned to array_2 // and then array_2 is assigned to array_1
The operator returns a non-const My_Array&
to allow chained assignments:
array_1 = (array_2 = array_3); // The assignment operator (=) has right-to-left associativity // array_3 is assigned to array_2 // and then array_2 is assigned to array_1
Note that this is allowed for basic types like int
.