Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

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:

  1. Copy constructor: A special constructor that creates a new object that is a copy of an existing object of the same class.

  2. Copy assignment operator: A special member function that copies the contents of one object into another object of the same class.

  3. 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.

  • No labels