Copy Assignment Operator and Move Assignment Operator in C++
The copy assignment operator and move assignment operator are special member functions in C++ that handle the assignment of one object to another.
- Copy assignment operator: T& operator=(const T b) or (T& b):
- don't pass non-constant rhs ref, like (T& b). It's allowed but may cause issue.
- If undefined: shallow-copy
- Move assignment operator: T& operator=(T&& b)
- Called when an object appears on the left-hand side of an assignment expression, where the right-hand side is an rvalue of the same or implicitly convertible type.
Code Example
This example demonstrates how to use the copy assignment operator and move assignment operator in C++ to manage object assignments efficiently. It also shows examples of copy constructor and move constructor, which helps to highlight their differences.
Explanation
Copy Constructor
MyClass(const MyClass& a) { // copy constructor
val = a.val;
cout << "copy constructor, val = " << this->val << endl;
}
- Creates a new object as a copy of an existing object.
- It copies the value of val from the source object a to the new object.
Copy Assignment Operator
MyClass& operator=(const MyClass& a) { // copy assignment operator
val = -a.val;
cout << "copy assignment operator, val = " << this->val << endl;
return *this;
}
- Assigns the value of one existing object to another.
- It negates the value of val from the source object a and assigns it to the current object.
- In this example, the behavior of the copy assignment operator is deliberately to be different from the copy constructor, so their outcome can be differented.
Move Constructor
MyClass(MyClass&& a) {
val = a.val;
cout << "move constructor, val = " << this->val << endl;
}
- Transfers ownership of resources from a temporary or moved object a to the new object.
- The val of the source object is assigned to the new object.
Move Assignment Operator
MyClass& operator=(MyClass&& a) {
val = -a.val;
cout << "move assignment operator, val = " << this->val << endl;
return *this;
}
- Transfers ownership of resources from a temporary or moved object a to an existing object.
- It negates the value of val from the source object a and assigns it to the current object.
- The behavior here is also deliberately created to be different from the move constructor.
main function
int main() {
MyClass m1; // default constructor
MyClass m2 = m1; // copy constructor
MyClass m3; // default constructor
m3 = m1; // copy assignment operator
MyClass m4 = move(m1); // move constructor
MyClass m5; // default constructor
m5 = move(m4); // move assignment operator
return 0;
}
- MyClass m1;: Creates an object m1 using the default constructor.
- MyClass m2 = m1;: Creates an object m2 using the copy constructor.
- MyClass m3;: Creates an object m3 using the default constructor.
- m3 = m1;: Uses the copy assignment operator to assign the value of m1 to m3.
- MyClass m4 = move(m1);: Creates an object m4 using the move constructor.
- MyClass m5;: Creates an object m5 using the default constructor.
- m5 = move(m4);: Uses the move assignment operator to assign the value of m4 to m5.
int main() {
MyClass m1; // default constructor
MyClass m2 = m1; // copy constructor
MyClass m3; // default constructor
m3 = m1; // copy assignment operator
MyClass m4 = move(m1); // move constructor
MyClass m5; // default constructor
m5 = move(m4); // move assignment operator
return 0;
}
Conclusion
Understanding the copy assignment operator and move assignment operator is essential for efficient object management and resource handling in C++. These operators help ensure that objects are assigned correctly, preventing resource leaks and unnecessary copies.