Lecture 10
The Shallow Copy Problem
When you copy an object, C++ by default copies each member value — a shallow copy. For objects that own heap memory, this creates two objects pointing to the same buffer:
The destructor of a frees the buffer. The destructor of b then tries to free the same memory —
a double free, which is undefined behavior (typically a crash).
To fix this, you must define a copy constructor and copy assignment operator that perform a deep copy — allocating fresh memory and copying the contents.
Copy Constructor
The copy constructor is called whenever an object is initialized from another object of the same type:
The parameter is const String& — pass by const reference to avoid triggering another copy and to
allow copying from const objects.
Copy Assignment Operator
The copy assignment operator is called when you assign one existing object to another:
The return type is String& to support chained assignment: a = b = c.
Self-Assignment
Without the guard if (this == &other) return *this, assigning an object to itself destroys its
own buffer before reading from it:
Always check for self-assignment at the top of operator=.
The Rule of Three
If a class needs any one of these, it almost certainly needs all three:
- Destructor — because the class owns a resource
- Copy constructor — to deep-copy that resource on initialization
- Copy assignment operator — to deep-copy and release the old resource on assignment
This is the Rule of Three. A class that defines a destructor for heap memory but omits the other two silently produces dangling pointers and double frees.
The standard library containers (std::vector, std::string) all follow this rule. Our String
class is a simplified version of std::string.
String with Full Copy Semantics
Exercises
Q1.
Without running the code, predict what this program prints — or describe what goes wrong.
Q2.
Without running the code, predict what this program prints (using correctly-implemented String
with a deep-copy constructor).
Q3.
Trace through this copy assignment step by step. At each checkpoint, describe the state of a
and b.
Q4.
Each snippet has a bug related to copy semantics. Identify what's wrong.
Q5.
Implement the copy constructor and copy assignment operator for String.
Practice Problems
- Design Linked List — Medium
- Copy List with Random Pointer — Medium
- Clone Graph — Medium