C++
Rule of five
Learn the rule of five and resource management.
Rule of five
The rule of five says: if a class defines a destructor, copy constructor or copy assignment, it probably needs all five.
The five members are: ~T() (destructor), T(const T&) (copy constructor), T& operator=(const T&) (copy assignment), T(T&&) (move constructor) and T& operator=(T&&) (move assignment). If a class manages a resource (raw pointer, file handle) and you only define the destructor, copying does a shallow copy and causes a double-free error. That is why writing all five is the safest approach.
Rule of zero
In modern C++ the rule of zero is preferred: if a class holds only resource-managing members like std::string, std::vector or smart pointers, you do not need to define any special members.
The compiler automatically generates correct move and copy operations for those members. Example: class Student { std::string name; std::vector<int> grades; }; needs no special members and everything works automatically. With raw pointers you need the rule of five; with smart pointers the rule of zero suffices. That is why modern C++ avoids raw pointers.
Exercise Add move members to the Buffer class
The Buffer class in the starting code already has a destructor, copy constructor and copy assignment (three of the rule of five). Add the move constructor and move assignment. In main move a into b with std::move and print b.data with std::cout.
Show example solution
#include <iostream>
#include <string>
#include <utility>
class Buffer {
public:
std::string data;
Buffer(std::string d) : data(d) {}
~Buffer() {}
Buffer(const Buffer& other) : data(other.data) {}
Buffer& operator=(const Buffer& other) { data = other.data; return *this; }
Buffer(Buffer&& other) : data(std::move(other.data)) {}
Buffer& operator=(Buffer&& other) { data = std::move(other.data); return *this; }
};
int main() {
Buffer a("Hello");
Buffer b(std::move(a));
std::cout << b.data;
return 0;
}
Test yourself
-
Match each of the five members to its role
- ~T()
- Destructor
- T(const T&)
- Copy constructor
- T(T&&)
- Move constructor
- T& operator=(T&&)
- Move assignment
-
How many members does the rule of five cover?
~T(); T(const T&); T(T&&);
T& operator=(const T&); T& operator=(T&&);
Show answer
Five — The rule of five covers five members.
-
Destructor signature
~____() { /* release the resource */ }
Show answer
~Buffer() { /* release the resource */ }
Next lesson: Summary - Move semantics