1. Problem It Solves
The Rule of Five completes manual ownership semantics, the Rule of Zero delegates ownership to RAII members, and noexcept tells containers moving cannot throw. It makes an important constraint visible instead of leaving readers to guess. This lesson keeps only the C++11 core that fits one focused day.
2. Prerequisites
The ideas from Day 19, plus basic variables, functions, and output already introduced.
3. Core Idea
Mental model: The Rule of Five completes manual ownership semantics, the Rule of Zero delegates ownership to RAII members, and noexcept tells containers moving cannot throw. Identify the relevant value or state, who owns it, and whether the rule acts during compilation or execution.
4. Minimal Syntax
Owner(Owner&& other) noexcept; Owner& operator=(Owner&& other) noexcept;5. How It Works
The example creates a tiny fixed state with no keyboard input.
C++11 or the standard-library contract applies today's rule.
The program prints the important result so it can be checked against the source.
6. Common Mistakes
Declaring a move operation
noexceptwhen it can actually throw causesstd::terminate; omitting a true guarantee may make containers copy instead.
7. When to Use It
Use it when reviewing ownership types, while preferring Rule of Zero for new code.
Avoid it when it hides ownership, lifetime, type, ordering, or cost.
8. Simple Example
A manual owner defines all five special operations with non-throwing moves, while a string-only type needs none of them. The .cpp keeps the data fixed and avoids unrelated abstraction.
Complete sample code
Source file
cpp11/20_rule_of_five_zero_noexcept_move/main.cpp
#include <iostream>
#include <string>
#include <utility>
class Owner {
public:
explicit Owner(int value = 0) : data_(new int(value)) {}
~Owner() { delete data_; }
Owner(const Owner& other) : data_(new int(*other.data_)) {}
Owner& operator=(const Owner& other) {
if (this != &other) {
*data_ = *other.data_;
}
return *this;
}
Owner(Owner&& other) noexcept : data_(other.data_) {
other.data_ = nullptr;
}
Owner& operator=(Owner&& other) noexcept {
if (this != &other) {
delete data_;
data_ = other.data_;
other.data_ = nullptr;
}
return *this;
}
int get() const { return data_ ? *data_ : -1; }
private:
int* data_;
};
struct RuleOfZero {
std::string label; // string manages its own resource
};
int main() {
Owner first(5);
Owner second(std::move(first));
RuleOfZero zero{"automatic"};
std::cout << second.get() << ' ' << zero.label << '\n';
}
9. Key Takeaways
The feature is part of the C++11 scope used in this course.
Understand its lifetime, ownership, type, and ordering consequences.
Compile with warnings and prefer the smallest form that makes the rule obvious.
10. Self-Check Questions
Easy — How do the Rule of Five and Rule of Zero differ in resource management? What does
noexcepton a move constructor promise?Medium — Read the small example described above. What value or state should it print, and which rule produces that result?
Hard — Find and explain the subtle bug in this situation: Declaring a move operation
noexceptwhen it can actually throw causesstd::terminate; omitting a true guarantee may make containers copy instead. What is the smallest C++11-safe correction?