Move Semantics vs Copy Semantics
Move vs copy semantics — ownership transfer, rvalue references and performance tradeoffs, explained with examples and interview Q&A.
Expected Interview Answer
Copy semantics duplicates an object’s resources so the source and destination each own independent data, while move semantics transfers ownership of a source object’s resources to the destination and leaves the source in a valid-but-empty state, avoiding the cost of duplication.
Copy semantics is what you get by default: copying a large object means allocating new memory and copying every byte or element, which is correct but can be expensive for heap-heavy objects like large buffers or containers. Move semantics, introduced in C++11 via rvalue references and the move constructor / move assignment operator, instead lets the destination "steal" the source’s internal pointers or handles directly and reset the source’s pointers to null, which is a constant-time operation regardless of the object’s size. The compiler automatically selects a move over a copy when the source is an rvalue — a temporary about to be destroyed, or an object explicitly cast with std::move — because there’s no reason to pay for a deep copy of something that’s going away anyway. After a move, the source object must remain in a valid state (safely destructible and assignable) even though its contents are unspecified; it must never be read as if it still holds meaningful data.
- Avoids expensive deep copies of temporary or about-to-be-discarded objects
- Makes returning large objects by value cheap (return value optimization plus move)
- Enables move-only types like unique_ptr that model exclusive ownership
- Keeps container operations like push_back/insert efficient for large elements
AI Mentor Explanation
Copy semantics is like a groundskeeper duplicating an entire pitch’s turf, soil composition and drainage system for a second stadium — expensive and slow, but both stadiums end up with fully independent playing surfaces afterward. Move semantics is like relocating an entire ready-built modular stand from one stadium to another: the crew doesn’t rebuild it from scratch, they detach it, transport the same physical structure, and reattach it at the new site, leaving the original site empty of that stand. One duplicates everything at real cost; the other transfers the same resource and empties the source.
Step-by-Step Explanation
Step 1
Copy: allocate new storage
Copy semantics allocates fresh memory or resources in the destination.
Step 2
Copy: duplicate every element
Every byte, field, or contained element is copied from source to destination, cost scales with size.
Step 3
Move: steal the source's handles
Move semantics has the destination take the source's internal pointers/handles directly, no allocation or duplication.
Step 4
Move: null out the source
The source's internal pointers are reset (e.g. to null) so it remains safely destructible without double-freeing the transferred resource.
What Interviewer Expects
- Clear articulation that copy duplicates while move transfers ownership
- Mention of rvalue references / std::move as the C++ trigger mechanism
- Understanding that a moved-from object must stay in a valid (if unspecified) state
- A concrete performance motivation, e.g. avoiding O(n) copies of large buffers/containers
Common Mistakes
- Thinking std::move actually moves anything by itself — it only casts to an rvalue reference, enabling the move overload to be selected
- Using a moved-from object as if it still holds its original data
- Forgetting that move constructors/assignment should be noexcept where possible so containers like std::vector use them instead of falling back to copies
- Assuming move semantics exists in every OOP language — Java, for instance, has no built-in move semantics; objects are reference types and assignment copies the reference, not the object
Best Answer (HR Friendly)
“Copy semantics means when you copy an object, you get a fully independent duplicate of its data, which can be expensive for large objects. Move semantics means instead of duplicating, you transfer ownership of the source object’s internal resources directly to the new object, which is much cheaper because nothing gets re-allocated or re-copied — the source is just left empty afterward. Move semantics is mainly a C++ concept introduced to avoid unnecessary deep copies of temporaries.”
Code Example
// Java objects are always reference types, and assignment copies the
// reference, not the underlying object -- Java has no compiler-level
// move semantics like C++'s rvalue references. This class simulates
// the *concept* of a move: transferring ownership and invalidating
// the source, which is exactly what C++ move semantics automates.
public class OwnedBuffer {
private byte[] data;
public OwnedBuffer(int size) { this.data = new byte[size]; }
// Deep copy: independent duplicate, cost scales with size (copy semantics)
public OwnedBuffer copy() {
OwnedBuffer result = new OwnedBuffer(0);
result.data = this.data.clone();
return result;
}
// Explicit "move": transfer ownership, invalidate the source (move-like)
public OwnedBuffer moveOut() {
OwnedBuffer result = new OwnedBuffer(0);
result.data = this.data; // steal the reference, no copy
this.data = null; // source is left empty/invalid, like a moved-from object
return result;
}
}Follow-up Questions
- What is an rvalue reference and how does it enable move semantics in C++?
- What state must a moved-from object be left in, and why?
- Why should move constructors be marked noexcept whenever possible?
- Does Java or Python have anything equivalent to C++ move semantics?
MCQ Practice
1. The key difference between move and copy semantics is?
Copy semantics duplicates the resource; move semantics transfers ownership from source to destination, avoiding duplication.
2. In C++, what triggers the compiler to prefer a move over a copy?
When the source is an rvalue, overload resolution prefers the move constructor/assignment over the copy versions.
3. After a C++ object is moved from, it must be?
A moved-from object must remain valid (safely destructible/assignable) even though its contents are unspecified.
Flash Cards
Copy semantics in one line? — Duplicates a resource so source and destination hold independent data.
Move semantics in one line? — Transfers ownership of a resource from source to destination, leaving the source valid but empty.
What triggers a move in C++? — The source being an rvalue — a temporary or something cast with std::move.
Post-move requirement? — The source must stay in a valid (though unspecified) state, safely destructible.