Let's finish up basic dynamic multi-dimensional arrays.

What we have is the same picture from last time which represents an M x N array. It is declared as

    int **A;
where A[i] contains the address of the ith row. This address equals &A[i][0]. We can express the address of the (i,j) entry as
    &A[i][j]     OR     A[i] + j

Functions that return pointers

We can have functions that return not only int, doubles, and other stuff but that return pointers too!

See Demo 2D-array-in-1D.cpp

Dynamic Arrays of Pointers

Notice that in Raindrops Ptr.cpp, we could have run a constructor on each drop as it was allocated:

    theDrops[dropCount++] = new drop(center);
What if we wanted a dynamic array of drops? This would look like:
We would declare this as
    drop **theDrops;
    .
    .
    .
    int maxDrops = ...;
    theDrops = new drop * [maxDrops];

For the life program we will have a 2-D array of ponters to cells. The cell constructor will have the following definition:

    cell::cell(int row, int column);
The colony class will look like
    public:
      colony(int rows, int cols);
      ~colony();
    private:
      cell ***cells;
Here is part of the constructor:
    cells = new cell ** [rows];

    for (int r = 0; r < rows; r++) {
      cells[r] = new cell * [cols];

      for (int c = 0; c < cols; c++)
        cells[r][c] = new cell(r, c);
      }
Graphically the game of life looks like:
The destructor will be defined as:
    for (int r = 0; r < rows; r++) {
      for (int c = 0; c < cols; c++)
        delete cells[r][c];

      delete [] cells[r];
      }

    delete [] cells;

Copying Object Values

What happens when the value of one object is copied into another object? The answer: It depends! The default action taken, unless you specify otherwise, which is that all member data is copied. If the member data is a pointer, the address in that pointer is copied. The data the pointer is pointing to is not.

See Demo NoCopyConstr.cpp

After intArray T = S; we have:
So changing S's array changes T's array. This is known as shallow copying.

What we want is deep copying, which looks like this:
Now the changes to S and T are independent from one another. We can get this effect by using a copy constructor.

See Demo CopyConstr.cpp

There are three times that a copy constructor is called:

  1. Declaration with initialization:
        intArray T = S;
  2. Copying actual into formal in call by value:
        void bozo(intArray T);
        .
        .
        intArray S(5);
        .
        .
        bozo(S);
  3. Copying return value back to the caller:
        intArray bozo(...)
        {
          intArray S;
          .
          . 
          return S;
        }
    
    
        ... bozo(...) ...
To Index Previous Next