Page excerpted from Copy Constructors topic of a second year course in Advanced Programming

Here is the declaration of a simple Array class with a constructor, destructor and a copy constructor.

The implementation of the copy constructor mimics the implicit copy constructor provided by the compiler. The mimicry is to allow the copy constructor to be traced into by the Teaching Machine

Trace through the program using linked view. set(Array array, double value) is an external function to set all elements in array to value.


Code Notes

1. Step into main to the declaration of Array A. Click stepOver ()once to create the A object. It appears, unititialized, in local memory and in the linked view and the constructor is loaded into the Expression Engine.

2. Click stepOver again to call the constructor which creates the actual space for the array in the heap and initializes it to all zeros.

3. Step into ()the set function, (which is not a member function).

4. Step again to initialize the first parameter, array. The copy constructor gets called because set passes array by value.

5. Step through the copy constructor while it constructs a shallow copy of A by copying only the fields in local memory. A and array now point at the same heap data.

6. On returning to the set function, step one more time to create space for and initialize val to 3.0 .

7. Step through the set function to load the heap area with 3.0 's. The process may be hastened by putting the cursor on the line with the closing } for set then clicking runToCursor ( ). The heap allocation should be filled with 3.0 's

8. Click on stepInto at the closing }. The destructor gets called to destruct the copy, array.

9. Click through the destructor. A's heap space gets deleted!

10. Follow a similar process for the remaining two examples on the page.


When the set is invoked on A, array is a copy of A because set passes by value.

The copy is a shallow one so the two share the actual array data.

When set is finished the destructor is automatically called, destroying A's data as well as array's.

Deep Copy

Here's a copy constructor for Array that does a deep copy.

Now set fails for the classic reason that it is being invoked on a copy.

The corrected version.

At this point a question is posed

What's the difference? Why did the "incorrect" version work before, but not now?

The incorrect version of set passes in an Array object by value. This means that a copy of the object gets made and the value gets set in that copy.

This worked in the case of a shallow copy because the copy and the original Array shared the same data in the heap.

So when that data area got set in the copy, it was set in the original as well.

Once we created a true deep copy, the data area was set in the copy but not in the original and the set data was lost once the set function was ended.

Passing the Array object to set by reference solves the problem.

 

Examples Shown in Full