Class assignment operator

Jan 17, 2009 at 5:09am
Hello all,

I've created an array class that is somewhat similar (in functionality) to the STL vector class.

My assignment operator is as follows:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class T>
array<T> &array<T>::operator= (const array<T> &other) {
      
      if (this != &other) {
               
         delete [] v;
         v = new T[other.size()];      //v is the array of values
         s = other.size();             //s is the array size
         for (int i=0; i<s; i++) v[i] = other[i]; //[] accesses elements of "other" member array
         
      }
      cout << "inside function" << endl; //just to let me know it's working
      return *this;

}


So, this works perfectly fine when I do this:

1
2
3
4
5
array<double> a;
for (int i=0; i<10; i++) a[i] = (double)i;

array<double> b;
b = a;


But, the following does not work:
1
2
3
4
array<double> a;
for (int i=0; i<10; i++) a[i] = (double)i;

array<double> b = a;


What seems to happen when performing the assignment in the declaration statement, somehow the address is copied rather than the values, although I don't see why.

When I manipulate "b" after doing the single-statement assignment, "a" also changes, and also the destructor for "a" fails, because "b" is deleted prior to "a" and their memory locations are the same. Doing a two-statement assignment makes everything work just fine, but I can't see why.
Jan 17, 2009 at 5:41am
Although I'm no guru, I think the reason that the address is copied rather than the actual values is because you're referencing the address when you put: const array<T> &other

Try changing your code to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class T>
array<T> &array<T>::operator= (const array<T> *other) {
      
      if (this != *other) {
               
         delete [] v;
         v = new T[other.size()];      //v is the array of values
         s = other.size();             //s is the array size
         for (int i=0; i<s; i++) v[i] = other[i]; //[] accesses elements of "other" member array
         
      }
      cout << "inside function" << endl; //just to let me know it's working
      return *this;

}


Again, I may be showing just how much I don't know. Just trying to provide some constructive feedback.
Last edited on Jan 17, 2009 at 5:43am
Jan 17, 2009 at 6:27am
No.

1
2
array<double> b;
b = a;


calls array<double>::array<double>() followed by
the assignment operator.

 
array<double> b = a;


calls the copy constructor only.

You need to implement a custom copy constructor. The default one given to you by the compiler, a member-wise copy, is not sufficient since you class requires taking deep copies of its pointer members.

There are other issues with your assignment operator such as exception safety that I won't go into.
Jan 17, 2009 at 6:44am
Thanks. I will not tackle exception handling right now, as I am teaching myself and am reluctant to learn any try/catch stuff at the moment as I haven't needed it yet.

This was all I had to do, create a constructor as follows:
1
2
3
4
5
6
7
8
9
10
template <class T>
array<T>::array(const array<T> &a) {
     
     if (this != &a) {
        v = new T[a.size()];
        s = a.size();
        for (int i=0; i<s; i++) v[i] = a[i];
     }
          
}


Very simple solution. Thanks again.
Last edited on Jan 17, 2009 at 7:09am
Jan 17, 2009 at 3:32pm
The if( this != &a ) check is redundant in the copy constructor because it can never be false.

However, now that you've essentially written the exact same code in the copy constructor and in the assignment operator, it is time to factor it out and make a common (helper) function.

Jan 17, 2009 at 6:00pm
Good call. Fixed that. Thanks.
Topic archived. No new replies allowed.