Reputation: 920
I am trying to understand the following 2 versions of implementation of assignment operator, which is used to assign the other dynamic array to the the instance (class DoubleVector
) it was called with.
version 1.
DoubleVector& DoubleVector::operator= (DoubleVector other)
{
swap(vector_, other.vector_);
swap(size_, other.size_);
return *this;
}
version 2.
DoubleVector& DoubleVector::operator= (const DoubleVector& other)
{
double* newVector = new double[other.size_]; // (Try to) allocate new memory
for (int i = 0; i < other.size_; i++)
{
newVector[i] = other.vector_[i];
}
delete[] vector_; // After allocation succeeded we can delete the old array
size_ = other.size_;
vector_ = newVector;
return *this;
}
My questions are:
other.size_ = 0
)?delete[] vector_;
) after the allocation succeeded? Is it necessary?Furthermore, for the version 2, can I just directly assign other
to the instance that "=" is called with?
e.g.
DoubleVector& DoubleVector::operator= (const DoubleVector& other)
{
for (int i = 0; i < other.size_; i++)
{
vector_[i] = other.vector_[i];
}
size_ = other.size_;
return *this;
}
Upvotes: 1
Views: 323
Reputation: 901
Notice that the array passed as a parameter to the two versions of copy operator is different.
In first case there is a DoubleVector value
parameter passed by value (copy of passed value is created with copy constructor or copy assignment operator, in this case listed below). Since function operates with copy of data copy is replacement with swap due to efficiency reasons. All corner cases (like other.size == 0
) will be processed correctly.
In the second case there is a const DoubleVector & value
parameter passed by const reference. No copying of data is performed and to guarantee that external data will not be modified the reference is const (generally it's a good practice to use const qualifiers where applicable). In this case we manually allocate memory for future array (since currently allocated array, if any, may differ in size). realloc
may also be used for that reason. Further internal pointer to array is set to newly allocated data: vector_ = newVector;
. Before that assignment we must return previously allocated memory by calling delete[] vector_;
. Otherwise there will be a memory leak. Consider 10^3 calls to this operator with array of 10^6 doubles.
The second method has one issue. There is no check on self-assignment:
DoubleVector& DoubleVector::operator= (const DoubleVector& other)
{
if (this == &other)
return;
...
}
Copying is a core concept of OOP. There are different solutions common in use: copy on write, reference copy, copy-swap idiom (mentioned in comments) and others. Additionally modern C++ introduces move concept.
Hope it helps.
Upvotes: 1
Reputation: 461
Upvotes: 0