Order of Evaluation in Assignments
Can I rely on the right hand side of a deep copy assignment being evaluated
before the memory on the left hand side is released and reallocated ? In the
following example, will the assignment A = A.Increment() work for all
compilers ?
#include <stdlib.h>
class IntegerArray
{
public:
IntegerArray();
IntegerArray(int length);
IntegerArray(const IntegerArray & rhs);
IntegerArray operator=(const IntegerArray & rhs);
~IntegerArray();
int GetLength() const;
int GetInteger(int k) const;
void SetInteger(int k,int entry);
IntegerArray Increment() const;
static int * intvec(int length);
static void del_intvec(int * q,int length);
private:
int * itsInteger; // array of integers indexed from zero
int itsLength; // length of array
};
int main()
{
IntegerArray A(5);
for (int j = 0; j < A.GetLength(); ++j) A.SetInteger(j,1);
// is this guaranteed to work for all compilers ?
A = A.Increment();
for (j = 0; j < A.GetLength(); ++j)
printf(" Entry %d is %d.\n",j,A.GetInteger(j));
return 0;
}
IntegerArray IntegerArray::Increment() const
{
IntegerArray dummy(itsLength);
for (int j = 0; j < itsLength; ++j) dummy.SetInteger(j,itsInteger[j]+1);
return dummy;
}
IntegerArray::IntegerArray() : itsInteger(0), itsLength(0)
{
}
IntegerArray::IntegerArray(int length) : itsLength(length)
{
// entries uninitialised
itsInteger = (itsLength > 0) ? intvec(itsLength) : 0;
}
IntegerArray::IntegerArray(const IntegerArray & rhs) :
itsLength(rhs.GetLength())
{
// copy constructor
itsInteger = (itsLength > 0) ? intvec(itsLength) : 0;
for (int j = 0; j < itsLength; ++j) itsInteger[j] = rhs.GetInteger(j);
}
IntegerArray IntegerArray::operator=(const IntegerArray & rhs)
{
// assignment (deep copy)
if (this == &rhs) return *this;
if (itsInteger != 0)
{
// release memory
del_intvec(itsInteger,itsLength);
itsInteger = 0;
}
itsLength = rhs.GetLength();
// allocate memory
itsInteger = (itsLength > 0) ? intvec(itsLength) : 0;
for (int j = 0; j < itsLength; ++j) itsInteger[j] = rhs.GetInteger(j);
return *this;
}
IntegerArray::~IntegerArray()
{
if (itsInteger != 0) del_intvec(itsInteger,itsLength);
}
int IntegerArray::GetLength() const
{
return itsLength;
}
int IntegerArray::GetInteger(int j) const
{
if (j < 0 || j >= itsLength)
{
printf(" Index out of range : IntegerArray::GetInteger.\n");
exit(1);
}
return itsInteger[j];
}
void IntegerArray::SetInteger(int j,int entry)
{
if (j < 0 || j >= itsLength)
{
printf(" Index out of range : IntegerArray::SetInteger.\n");
exit(1);
}
itsInteger[j] = entry;
}
int * IntegerArray::intvec(int length)
{
return (new int[length]); // array of integers
}
void IntegerArray::del_intvec(int * q,int length)
{
delete [] q; // delete array of integers
}