Home Page
The Basics
Arrays
Classes
Abstract Data Types
Dynamic Memory Allocation

Lists
C++ Style Strings
Linked Lists
Stacks and Queues
Variable Data Types
Templates
Sorting
Overloading

Note:  In any assignment operator there are five things you need to worry about. and they need to be performed in the following order:

check for assignment to self.  If it is so, skip to step five.
delete/free memory associated with the instance
allocate new memory
make the copy
return *this (or this or current instance)

In Vector class…

Vector & Vector::operator = (const Vector &v)
{
   // step 1
   if (this == &v)  // checks address of this instance and passed &v
      return *this;

   // step 2
   delete [] data;
   len = v.len;

   // step 3
   data = new float[len];

   // step 4
   for (int i=0; i<len; i++)
      data[i] = v.data[i];

   // step 5
   return *this;
}

notice that from the second line of step 2 through the assignment loop of step 4 is identical as the copy constructor.

The key difference is that the copy constructor assumes uninitialized instance whereas in the assignment operator, current instance is initialized because it is the left-hand side of the argument.


Example:

String s1 = "Hello"
This is not calling the assignment operator, it calls the constructor because s1 is not initialized.

String s2 = s1;
This calls the copy constructor because s2 is being created and not initialized.

String s3;
s3 = s2;
First calls the default constructor for the first line.  Then calls the operator assignment on the second line because it's already been initialized by the constructor.

Point 1 Explained:
say for example the following is set:

Vector v1(ar1, 3);
Vector & v4 = v1;  // any change to one will go to other too
Vector v5;

what if you say v4 = v1 or v5 = v5 ? (assignment to self)
Step through the overloaded operator=  starting with step 2.

omit step one for reason of explanation
delete memory
allocate new memory
copy??  Where can you copy from.  The memory is deleted.

To fix this you need to check when you're assigning to self, do nothing.  Hence, Step 1


Point 5 Explained:
recall what we know about chaining…

s1=s2=s3=s4;  // chaining always evaluates right to left

this is the same as:
(s1 = (s2 = (s3=s4)));

because of this, we need the same in operator= overloading. so.. the return type is a re3ferancde to the same type.

Vector & Vector::operator = (const Vector &v)

this explains the need to return a de-referenced this in step 5 above.

To concatenate two vectors together:

Vector v5;  // assume initialized and containing (6, 8, -9, -1.2)
Vector v6;  // assume initialized and containing (1, 2)
Vector v7;

v7 = v5+v6;  // want v7 to contain (6, 8, -9, -1.2, 1, 2)

if v8 = v6; and you want to code v8 = v8+4.0; and also v8 += 3.0; we need to overload the +operator.  This will be done in two versions.






Version 1 (for v8 = v8 + 4.0)
Vector Vector::operator+ (float f)const
{
   Vector result;

   result.len = len +1;
   result.data = new float[len+1];
   for(int i=0; i<len; i++)
      result.data[i] = data[i];
   result.data[len] = f;

   return result;
}

Version 2 (for v7 = v5 + v6)

Vector Vector::operator+ (float first, float second)const
{
   Vector result;

   result.len = first.len + second.len;
   result.data = new float[result.len];
     int i=0;
   for(; i<first.len; i++)
      result.data[i] = first.data[i];
   for(; i<result.len; i++)
      result.data[i] = second.data[i];

   return result;
}

operator += (for v8 += 3.0)
This is changing current instance and making DMA larger.  You can't free up memory first.  You must copy over the data in v8 to a new pointer and then reallocate memory for v8 and copy original data into new memory and now add the 3.0.  Then, and only then, free up original memory for v8 which was in the new pointer.

Vector Vector::operator +=(Vector  v)
{
     // create temporary instance
     Vector temp;
     temp.len = len + v.len;
     temp.data = new double[temp.len];
     int i=0;

     // make copy
     for(; i<len; i++)  // note empty first space, i is already zero
          temp.data[i] = data[i];

     // add the second vector
     for(; i<temp.len; i++)
          temp.data[i] = v.data[i];

     // re-allocate memory for original
     delete [] data;
     data = new double[temp.len];

     // copy back into original
     for(i=0; i<temp.len; i++)
          data[i] = temp.data[i];
     len = temp.len;
     return *this;
}