Copy Constructors and Assignment Operators
Reading: Dietel Chapter 8
Dynamically Allocated Memory Problems
- Can use constructors to allocate memory at class instantiation
- But what if we copy one instantiation into another?
- This happens during:
parameter passing, function return values, initializing one instantiation to another- Don't want two objects pointing to the same memory (usually)
- Use copy constructors to avoid this
- A default is provided, but simply copies each member -- not sufficient
Copy constructor for our Array class:
Array :: Array ( const Array& A )
{
array_size = A.array_size; // can copy this member directlydata_elements = new int [ array_size ]; // must allocate new memory
for ( int i=0; i < array_size; i++ ) // want same contents in new memory
data_elements [ i ] = A.data_elements [ i ];
}Syntax notes
- must use this parameter signature
- parameter passed by reference ( & syntax ) since copy constructor defines how objects of this type are to be copied
Preventing Leaks of Dynamically-Allocated Memory
- Consider the following code:
Array a1(8), a2(10);
// some code to modify the contents of a1, a2
a2 = a1;- Default = operator just performs memberwise copy between a1, a2
- We know we want a2 to get its own 8-long array with same contents as a1
- But what about the 10-long array originally allocated for a2?
- We need to change the behavior of = to take care of these concerns
Assignment operator for Array class:
Array& Array :: operator = (const Array& rhs){if ( this != &rhs ) // so we don't clobber during self-assignment{
delete [ ] data_elements; // free memory previously allocated to lhsarray_size = rhs.array_size; // copy rhs size into lhs
data_elements = new int [ array_size ]; // allocate new size array
for (int i = 0; j < array_size; i++ ) // copy array contents of rhsdata_elements[ i ] = rhs.data_elements [ i ];
}return *this;
}Syntax notes:
- We want to emulate behavior of built-in = operator on statements like:
int x, y, z;- y = x = z;
We want to assign z to x, and then assign that value to y.
Precedence and associativity already defined; we need only return a
(reference to) the value assigned.- x = x;
This is allowed by the language; we want to make sure we don't
modify the rhs.
Perform the check this != &rhs before modifying this- ( x = y ) = z;
Generally useless, but can be done.
Assignment must return a (non-const) reference to the (lhs) Array.