IAM

SEPTEMBER2016

READING

A. Koenig, B. Moo. C++ Made Easier: The Rule of Three. 2001.
C++

Koenig and Moo provide some basic examples to emphasize the importance of the rule of three in C++ programming. They define the rule of three as follows:

  1. If a class has a non-empty destructor, it nearly always needs to define a copy constructor and assignment operator.
  2. If a class has non-trivial copy constructor or assignment operator, it usually needs both plus a destructor.

The first aspect gets apparent from the following (slightly adapted) example:

template<typename T>
class ArrayVector
{
    ArrayVector(int size): data(new T[size])
    {
    
    }
    
    ~ArrayVector()
    {
        delete[] data;
    };
    
    int& operator[](int i)
    {
        return data[i];
    }

    const int& operator[](int i) const
    {
        return data[i];
    }

private:
   T* data;
}

Now, using the class as follows will cause the destructor to call delete[] on both v1.data and v2.data:

int main()
{
    ArrayVector<int> v1(10);
    ArrayVector<int> v2 = v1;
}

Note that the source of trouble is the destructor and not the data pointer as removing the destructor would resolve the problem (while introducing a memory leak). A solution is to write a proper copy constructor and assignment operator.

Concerning the second aspect, non-trivial copy constructor refers to any copy constructor doing more than "just" copying data (or less than the default copy constructor). In the above example, implementing a (deep) copy constructor also implies the need for a destructor, thus, illustrating the second part of the rule. While a destructor almost always implies the need for a copy constructor and assignment operator, the reverse is not always true as illustrated by the case where the copy constructor deliberately copies less than the default one.

What is your opinion on this article? Let me know your thoughts on Twitter @davidstutz92 or LinkedIn in/davidstutz92.