Assignment Operator
Master the assignment operator to control object assignment and handle self-assignment correctly
Learn how to implement the assignment operator to control what happens when one object is assigned to another already-existing object.
A Simple Example
#include <iostream>
#include <cstring>
class String {
private:
char* data;
int length;
public:
String(const char* str = "") {
length = std::strlen(str);
data = new char[length + 1];
std::strcpy(data, str);
}
String(const String& other) {
length = other.length;
data = new char[length + 1];
std::strcpy(data, other.data);
}
String& operator=(const String& other) {
if (this == &other) {
return *this;
}
delete[] data;
length = other.length;
data = new char[length + 1];
std::strcpy(data, other.data);
std::cout << "Assignment: " << data << "\n";
return *this;
}
~String() {
delete[] data;
}
void display() const {
std::cout << data << "\n";
}
};
int main() {
String s1{"Hello"};
String s2{"World"};
std::cout << "Before assignment:" << "\n";
s1.display();
s2.display();
s1 = s2;
std::cout << "After s1 = s2:" << "\n";
s1.display();
s2.display();
s1 = s1;
std::cout << "After self-assignment s1 = s1:" << "\n";
s1.display();
return 0;
}
Breaking It Down
Assignment vs Initialization
-
Initialization: Creating a new object -
String s1{"Hello"};orString s2 = s1; -
Assignment: Overwriting an existing object -
s1 = s2;where s1 already exists - Assignment must clean up old resources before copying new ones
- Remember: Assignment operator only called on existing objects
Self-Assignment Check
-
What it does:
if (this == &other) return *this;prevents assigning to yourself -
Why it matters: Without it,
obj = objdeletes data then tries to copy from deleted memory - How it works: Compares addresses - if same object, return immediately
- Remember: Always check for self-assignment in assignment operators
Clean Up Before Copy
- Step 1: Check self-assignment
-
Step 2: Delete old resources -
delete[] data; - Step 3: Allocate new resources and copy
-
Step 4: Return
*thisto enable chaining - Remember: Forgetting to delete causes memory leaks
Return Type: ClassName&
-
Must return reference to
*thisfor chaining:a = b = c; -
Return type:
String& operator=(const String& other) - Why reference: Avoids unnecessary copies, enables chaining
-
Remember: Return
*this, notthis- dereference the pointer
Why This Matters
- Assignment (`obj1 = obj2`) is different from initialization. It assigns to an already-existing object, which means you must clean up the old resources first.
- Without a proper assignment operator, you get memory leaks (old resources not freed) and crashes (shallow copies).
- This completes the Rule of Three - destructor, copy constructor, and assignment operator work together for correct resource management.
- Every production C++ class managing resources needs this.
Critical Insight
The copy-and-swap idiom is a clever technique that makes assignment operators exception-safe and automatically handles self-assignment:
String& operator=(String other) { // Pass by value!
std::swap(data, other.data); // Swap resources
std::swap(length, other.length);
return *this; // other's destructor cleans up old data
}
By passing the parameter by value instead of const reference, the copy constructor handles copying. Then we swap resources with the temporary. When the temporary dies, it cleans up our old data. Elegant and exception-safe!
Best Practices
Always check for self-assignment: Use if (this == &other) return *this; to prevent bugs.
Delete old resources before allocating new: This prevents memory leaks.
Return *this by reference: Enables assignment chaining like a = b = c;.
Consider copy-and-swap idiom: For exception safety and cleaner code in complex classes.
Common Mistakes
Not checking self-assignment: obj = obj crashes without the check.
Memory leak: Forgetting to delete old data before assigning new.
Not returning *this: Assignment should return reference for chaining.
Exception safety: If allocation fails mid-assignment, object is left in invalid state.
Debug Challenge
This assignment operator has a critical bug. Click the highlighted line to fix it:
Quick Quiz
- Why check for self-assignment?
- What should assignment operator return?
- What's the correct order of operations in assignment?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once