The Rule of Five is a concept in C++ that refers to a set of five special member functions that a class may need to define when it manages a resource that requires explicit memory management or has complex ownership semantics. These five member functions are:
The default constructor
The copy constructor
The move constructor
The copy assignment operator
The move assignment operator
The Rule of Five states that if a class needs to define any one of these five functions, it should define all five of them. This is because the default implementations provided by the compiler may not correctly manage the resources that the class is responsible for, leading to bugs or memory leaks.
For example, consider a class MyString that manages a dynamically allocated string. This class would need to define a custom destructor to free the memory allocated for the string, as well as the other four member functions to manage the string’s ownership semantics:
class MyString {
public:
// Default constructor
MyString() : str(nullptr), len(0) {}
// Constructor that creates a string from a character array
MyString(const char* s) {
len = strlen(s);
str = new char[len+1];
strcpy(str, s);
}
// Copy constructor
MyString(const MyString& other) : len(other.len) {
str = new char[len+1];
strcpy(str, other.str);
}
// Move constructor
MyString(MyString&& other) : str(other.str), len(other.len) {
other.str = nullptr;
other.len = 0;
}
// Copy assignment operator
MyString& operator=(const MyString& other) {
if (this != &other) {
delete[] str;
len = other.len;
str = new char[len+1];
strcpy(str, other.str);
}
return *this;
}
// Move assignment operator
MyString& operator=(MyString&& other) {
if (this != &other) {
delete[] str;
str = other.str;
len = other.len;
other.str = nullptr;
other.len = 0;
}
return *this;
}
// Destructor
~MyString() {
delete[] str;
}
private:
char* str;
size_t len;
};
In this example, the MyString class defines all five of the special member functions to manage the ownership of the dynamically allocated string. The copy constructor and copy assignment operator create a deep copy of the string, while the move constructor and move assignment operator transfer ownership of the string to the new object. The destructor is responsible for freeing the memory allocated for the string.
The Rule of Five is important because it ensures that a class that manages a resource behaves correctly and consistently with respect to memory management and ownership semantics. By defining all five of these special member functions, you can prevent bugs and memory leaks in your code and ensure that your classes are well-behaved and easy to use.