Lecture 11
Lvalues and Rvalues
Every expression in C++ is either an lvalue or an rvalue:
- lvalue — has a name and a persistent address. Can appear on the left side of
=. - rvalue — a temporary with no name. It exists only for the duration of the expression.
When you copy a temporary into a new object, the temporary is about to be destroyed anyway — the copy is unnecessary work. Move semantics let you steal the temporary's resources instead.
Rvalue References
An rvalue reference (&&) binds only to rvalues. It lets you write overloads that the compiler
selects specifically when working with temporaries:
Move Constructor
The move constructor takes an rvalue reference and steals the source's resources:
Two things happen:
thistakes ownership ofother's buffer — no heap allocation needed.other's members are zeroed so its destructor (delete[] nullptr) is a no-op.
noexcept tells the compiler this operation cannot throw. Standard containers like std::vector
require it to choose the move constructor over the copy constructor during reallocation.
Move Assignment Operator
Like copy assignment, but steals instead of deep-copying:
std::move
An lvalue can be explicitly cast to an rvalue reference with std::move. This signals: "I am
done with this object; you may steal from it."
After std::move(a), a is in a valid but unspecified state. You can destroy it or assign a
new value to it, but you must not read from it first. Using a moved-from object is a common source
of bugs.
std::move does not move anything — it just performs the cast. The actual resource transfer
happens inside the move constructor or move assignment operator.
The Rule of Five
The Rule of Three from Lecture 10 expands to the Rule of Five in modern C++:
If you define any of these, define all five:
- Destructor
- Copy constructor
- Copy assignment operator
- Move constructor
- Move assignment operator
Omitting the move operations does not break correctness — the compiler falls back to copy — but it leaves performance on the table everywhere the compiler could have moved instead.
String with Full Move Semantics
Exercises
Q1.
Without running the code, predict what this program prints.
Q2.
Without running the code, predict what this program prints.
Q3.
Each snippet has a bug related to move semantics. Identify what's wrong.
Q4.
Implement the move constructor and move assignment operator for String.
Practice Problems
- LRU Cache — Medium
- Design Twitter — Medium