Rule Of Three in C++

This rule basically states that if a class defines one(or more) of the following, it should probably explicitly define all three, which are:

Now let us try to understand why?
The default constructors and assignment operators do shallow copy and we create our own constructor and assignment operators when we need deep copy (For example when class contains pointers pointing to dynamically allocated resources)

First, what does a destructor do? It contains code that is supposed to run whenever an object is destroyed. To only affect the contents of the object would be useless. An object in the process of being destroyed cannot have any changes made to it. Therefore, the destructor affects the program’s state as a whole.



Now, supposing our class does not have a copy constructor. Then copying an object will copy all of its data members to the target object. What happens when these objects are destroyed? The destructor runs twice. Also the destructor has the same information available for each object being destroyed. That sums up as, in the absence of a copy constructor, the execution of the destructor, which is supposed to happen once, happens twice. This duplicate execution, is a source for trouble.

A coding example as follows:

filter_none

edit
close

play_arrow

link
brightness_4
code

// In the below C++ code, we have created
// a destructor, but no copy constructor
// and no copy assignment operator.
class Array
{
private:
    int size;
    int* vals;  
   
public:
    ~Array();
    Array( int s, int* v );
};
   
Array::~Array()
{
   delete vals;
   vals = NULL;
}
   
Array::Array( int s, int* v )
{
    size = s;
    vals = new int[ size ];
    std::copy( v, v + size, vals );
}
   
int main()
{
   int vals[ 4 ] = { 11, 22, 33, 44 }; 
   Array a1( 4, vals );
  
   // This line causes problems.
   Array a2( a1 );
  
   return 0;
}

chevron_right


In the example above, once the program goes out of scope, the class destructor is called, not once but twice. First due to deletion of a1, and then of a2. The default copy constructor makes a copy of the pointer vals and does not actually allocate memory for it. Thus, on deletion of a1, the destructor frees up vals. All subsequent vals containing instances when trying to be deleted by the destructor, causes the program to crash, as vals does not exist anymore.

This is similar in the case of copy assignment operator. If a class does not have an explicitly defined assignment operator, implicit assignment of all source’s data members to the target’s corresponding data members will occur. All in all, it creates a copy, which again is the same problem defined previously.

References:

This article is contributed by Nihar Ranjan Sarkar. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up
Article Tags :
Practice Tags :


1


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.