The "Rule of Three" is a guideline in C++ that states that if a class defines any of the following three special member functions, it should also define the other two:
Copy constructor: A special constructor that creates a new object that is a copy of an existing object of the same class.
Copy assignment operator: A special member function that copies the contents of one object into another object of the same class.
Destructor: A special member function that is called when an object of the class is destroyed, and is used to clean up any resources that the object has allocated during its lifetime.
The reason for the "Rule of Three" is to ensure that the class behaves correctly in all situations, and to avoid memory leaks or other problems that can arise from inconsistent memory management.
For example, if a class has a dynamically allocated memory resource that is managed by the constructor and destructor, it is important to define the copy constructor and copy assignment operator to properly handle copying the memory resource from one object to another. If these functions are not defined, the default implementations provided by the compiler may simply copy the pointer to the memory resource, resulting in two objects pointing to the same memory location. This can cause problems if one object is destroyed or modified, leaving the other object with a dangling pointer or invalid data.
Here is an example of a class that follows the Rule of Three:
class MyClass { public: MyClass(); // Default constructor MyClass(const MyClass& other); // Copy constructor MyClass& operator=(MyClass rhs); // Copy assignment operator ~MyClass(); // Destructor private: int* data; int size; }; MyClass::MyClass() { size = 10; data = new int[size]; } MyClass::MyClass(const MyClass& other) { size = other.size; data = new int[size]; for (int i = 0; i < size; i++) { data[i] = other.data[i]; } } MyClass& MyClass::operator=(MyClass rhs) { swap(size, rhs.size); swap(data, rhs.data); return *this; } MyClass::~MyClass() { delete[] data; } int main() { MyClass obj1; MyClass obj2 = obj1; // Use copy constructor MyClass obj3; obj3 = obj2; // Use copy assignment operator return 0; }
In this example, the MyClass
class has a dynamically allocated array data
that is managed by the constructor and destructor. The copy constructor and copy assignment operator have been defined to create deep copies of the data
array, and the destructor deallocates the memory when the object is destroyed.
By following the Rule of Three and defining all three special member functions, the MyClass
class can be used safely and consistently in all situations, and avoids any issues with memory management or data consistency.