Copy constructors

One of the handiest actions is to be able to clone, or create copies of objects, hence the notion of a copy constructor: a constructor that takes one object as a parameter and builds a duplicate of it.

For the most part this can be done by simply copying fields, but an exception must be made for classes that utilize dynamically allocated memory. For these we don't want to simply copy the pointer to the original object's memory, we want to allocate our own section of memory and copy the appropriate data across.

The example below shows a copy constructor for a NumericArray class.
NumericArray::NumericArray(const NumericArray& src);

If we already had one numeric array variable, say NA1, and we wanted to create a second, say NA2, that was a copy of the first one we could use the syntax
NumericArray NA2(NA1);

Note that the parameter for the constructor is passed by reference (with the & symbol) and yet is passed as a const. This is a common convention in C++ copy constructors, for the following reason:

The code for the copy constructor, as well as another constructor example accepting other parameters, is provided below.

class NumericArray {
   private:
      // NumericArray will store an array of 'size' doubles
      double *arr;
      int    size;

   public:
      // constructor to create an array of doubles,
      //    optional parameters to specify the size
      //    and initialization values, 
      //    defaulting to 10 and 0
      NumericArray(int sz = 10, int val = 0);

      // copy constructor, allowing us to make
      //     one array a duplicate of another,
      // e.g.  NumericArray  A(5, 1);
      //       NumericArray  B(A); // B is a copy of A
      NumericArray(const NumericArray& src);

};

NumericArray::NumericArray(int sz, int val)
{
   // set default values for empty array
   arr = NULL;

   // try to allocate array of specified size
   if (sz > 0)
      arr = new double[sz];
   if (arr == NULL) size = 0;
   else {
      size = sz;
      for (int i = 0; i < size; i++)
          arr[i] = val;
   }
}

NumericArray::NumericArray(const NumericArray& src)
{
   if (src.arr == NULL) {
      arr = NULL;
      size = 0;
   } else {
      arr = new double[src.size];
      if (arr == NULL) size = 0;
      else {
         size = src.size;
         for (int i = 0; i < size; i++) {
             arr[i] = src.arr[i];
         }
      }
   }
}