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.
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.
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.
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];
}
}
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.