Overloading Error Free Assignment Operator

Written by Raza on. Posted in C++

Assignment is not a simple task in object oriented programming. It may take you a day to trace out an error that is happening because of incorrect assignment, let alone fix it. In a post before, I dealt with some issues while assigning one object to another. Still there are some issues associated with it. So I shall write a code and explain to you its errors. Kindly Follow this piece of Code. 


<p>class Vector</p>
<p>public :</p>
<p>.  int *ptr ;</p>
<p>.  int size ;</p>
<p>.  Vector ()</p>
<p>.  {</p>
<p>.    ptr = NULL ;</p>
<p>.    size = 0 ;</p>
<p>.  }</p>
<p>.  const Vector&amp; operator = (const Vector &amp;) ;</p>
<p>} ;</p>


<p>const Vector&amp; Vector :: operator = (const Vector &amp;obj)<br />
<p>if (this != &amp;obj)</p>
<p>{<br />
.  size = obj.size ;<br />
.  delete [] ptr ;<br />
.  ptr = new int [size] ;</p>
<p>.  for (int i = 0 ; i &lt; size ; ++i)<br />
.   ptr[i] = obj.ptr [i] ;<br />
<p>return *this ;<br />
}<br />
int main ()<br />
{<br />
Vector v1, v2 ;<br />
v1.ptr = v2.ptr ;<br />
v1 = v2 ;<br />


The above written code revolves around overloading assignment operator. Do you see any error in it? Well even if you do, let me explain some of the errors or improvements in this code. 

      1. Declare Data Members Private:

To begin, the data members in a class should almost always be private. Don’t take the risk of declaring them public just because you feel tired of writing getters and setters. The big problem which arises next is nearly eliminated if you declare your data members private. Access those members using getters and setters and overload indexing operator to access one index of the array.

      2. Const Return Type of Assignment Operator:

Look at the prototype of the function. You are returning const Vector&. Well, it’s not any sort of danger or error but it is better if you do not use const. Usually const is used so that programmer cannot change the associativity of the operator. Look here.

<p>(v1 = v2) = v3 ;</p>

If you return const, then this statement would not execute. But the point is: why not allow the programmer to do so? There is no such harm in that. Return just the reference to the object.

      3. Dangling Pointer:

Come to the second line in main. You simply point the array of first object to the location where array of second object is pointing. Now come inside the overloaded function for assignment operator. You have placed a check against self-assignment as we discussed in overloading equality operator. Quite nice! After that you delete the previous array of the object and then try to copy the data of array of the second object. Oops!!! Here is where you are wrong. Arrays of both the object were actually the same location. So when you deleted one, the other automatically got deleted. Thus the pointer of second array becomes a dangling pointer.

This may lead to unforeseen errors in your program. To avoid this situation, make sure that inside your assignment operator function, check whether the arrays of both the objects point to the same location or not? A good programmer not only prevents a dangerous situation but also implement its solution. So placing a check is not sufficient. Try to remove that error you did in the first place, in the main function. Delete the first array only if both arrays are different. If they are not different, just allocate new memory to the first array and copy the data of second array into it.

Here is the modified version of the code for assignment operator.

<p>Vector&amp; Vector :: operator = (const Vector &amp;obj)<br />
{<br />
if (this != &amp;obj)<br />
{<br />
.  size = obj.size ;<br />
.  if (ptr != obj.ptr)<br />
.  {<br />
.   delete [] ptr ;<br />
.  }</p>
<p>ptr = new int [size] ;<br />
for (int i = 0 ; i &lt; size ; ++i)<br />
. ptr[i] = obj.ptr [i] ;<br />
}<br />
return *this ;<br />


See, do your list of errors matches that of mine or there is something else to be added up. Feel free to do so in the comments.


Tags: , , , , , ,