-1

Three classes Zoo, ZooObject and Animal are present.Is it valid to declare a 2D array of ZooObjects like mentioned below? If so, how do i initialise it? I am familiar with dynamically allocating a 2D array, but can't figure out this one.

class ZooObject;

class Zoo {
 public:
  int rows, cols;
  ZooObject ***zooArray;

  Zoo(int rows, int cols) {
    this->rows = rows;
    this->cols = cols;
    // dynamically initialize ***zooArray as a 2D array with each 
    //element of type Animal
    // initially initialized to NULL.


 // initialize each row first.
    for (i = 0; i < rows; i++) {
      zooArray[i] = new ZooObject *[cols];
    }

    // initialize each column.
    for (i = 0; i < rows; i++) {
      for (j = 0; j < cols; j++) {
        Animal animal;
        zooArray[i][j] = &animal;
      }
    }
  }
};

class ZooObject {
 public:
  bool isAlive;
};

class Animal : public ZooObject {
 public:
  bool isHerbivore;
};

int main() { Zoo *zoo = new Zoo(3, 3); }
taurus05
  • 2,491
  • 15
  • 28

1 Answers1

2

As already was mentioned, here is nice post where the general answer to the question was detailing explained. How do I declare a 2d array in C++ using new?

In your case, if you want to store this as 2D array. You should allocate first all rows, where each row is a ZooObject**, which is ZooObject `s pointers array. And after, for each of the row, you should allocate the array (columns) of ZooObject*. You will have something like this:

    Zoo(int rows, int cols) {
        this->rows = rows;
        this->cols = cols;

        zooArray = new ZooObject**[rows];
        for (int i = 0; i < rows; ++i) {
            zooArray[i] = new ZooObject*[cols];
            for (int j = 0; j < cols; ++j) {
                zooArray[i][j] = nullptr;
            }
        }
    }

However, consider using 1D arrays, you still can access it via 2 dimensions, via corresponding method, which converting rowId, colId pair to 1D dimension.

Also, don't forget to delete which you new!

Bonny Cash
  • 36
  • 3
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 11 '21 at 20:30
  • I can even have further classes inheriting from the base class Animal like Carnivorous, Herbivorous etc. Hence, Animal will be an abstract class. I believe this initialisation `zooArray[i][j] = new Animal;` will throw error. – taurus05 Oct 11 '21 at 20:32
  • 1
    @taurus05, you are right. We can store any of the derived classes object in the cell, as the cell has the type `ZooObject*`. `new Animal` is an example. It's better to assign `nullptr` there, and later assign the correct object that we want. – Bonny Cash Oct 11 '21 at 20:43
  • @BonnyCash Thank you! – taurus05 Oct 11 '21 at 20:46
  • When you say you want a 2D array, I think there should be just one allocation, no arrays of pointers. – WilliamClements Oct 11 '21 at 20:51
  • I want a 2D array of pointers. – taurus05 Oct 11 '21 at 20:57
  • @taurus05 you need a virtual desctructor in your base class (it is *unusable* without a virtual destructor) and then you need more virtual functions (it is *not very useful* without them). "I believe this initialisation zooArray[i][j] = new Animal; will throw error". Why do you think so? It is certainly infinitely better than `Animal animal; zooArray[i][j] = &animal;`. – n. m. could be an AI Oct 11 '21 at 21:13