Я пытаюсь получить доступ к массиву room через функции в самом классе комнаты, то есть:

 class ship{

    room * rooms[3][4];
 public:

   room ** getrooms(){

       return *rooms;
   }

 }


class room{

  //variables...
  ship * ship_ptr;
  public:
     getShipPtr(); //assume it returns the pointer to the class ship
     void function_x(){
    this->getShipPtr()->getrooms()->rooms[x][y]->doThat();
      }
  }

Я делаю что-то не так с указателем, но я не совсем уверен, что можно исправить в коде, чтобы я мог получить доступ к массиву комнаты из класса корабля? Примечание. Предположим, что комнаты уже запущены.

0
Zetsuno 5 Янв 2016 в 23:22

3 ответа

Лучший ответ

Я делаю что-то не так с указателем, но не совсем уверен

Вы делаете ложное предположение, что двумерный массив может распасться на указатель на указатель так же, как одномерный массив может распасться на указатель.

int arr1[10];
int* ptr1 = arr1; // OK. 1D array decays to a pointer.

int arr2[10][20];
int** ptr2 = arr2; // Not OK. 2D array does not decay to a pointer to pointer.

int (*ptr2)[20] = arr2; // OK. ptr2 is a pointer to "an array of 20" objects.

Мое предложение:

Упростите свой код и измените интерфейс на:

room* getRoom(size_t i, size_t j){
   // Add checks to make sure that i and j are within bounds.
   return rooms[i][j];
}
3
R Sahu 5 Янв 2016 в 20:40

Я не собираюсь настаивать на использовании std::vector и т. Д., Хотя ваш учитель должен научить вас использовать их с самого начала. Так что давайте продолжим писать C на C ++. Вы не можете вернуть двумерный массив как двойной указатель, поскольку первый не распадается на второй. Если вы настаиваете на возвращении указателя на свой массив, вам нужно

room* (*getrooms())[4] // define a function returning a pointer to array-4 of room*
{
    return rooms;
}

Это потому, что 2D-массив типа, например. T arr[A][B] распадается на указатель на массив-B T.

1
vsoftco 5 Янв 2016 в 20:50

Я считаю, что основная причина вашей проблемы - это циклическая зависимость от того, что rooms знает о ship и ship знает о rooms.

Предлагаю другой дизайн:

class Ship
{
  Room ship_rooms[3][4];  // Note, not dynamically allocated.
  public:
    void move_unit(Room& from_room, Room& destination)
    {
      destination.set_unit(from_room.get_unit());
    }
    void move_unit(unsigned int from_row, unsigned int from_column,
                   unsigned int dest_row, unsigned int dest_column)
    {
      ship_rooms[dest_row][dest_column].set_unit(ship_rooms[from_row][from_column].get_unit());
    }
    Room& get_room(unsigned int row, unsigned int column)
    { return ship_rooms[row][column]; }
};

В приведенном выше проекте Ship отвечает за перемещение юнитов между комнатами. Комнаты будут получать (вырезать) единицы или устанавливать единицы (получать их). Это избавляет от необходимости иметь комнату, чтобы что-либо знать о Корабле.

Другой возможный вариант - переместить что-то из одной комнаты в другую:

class Room
{
  Item unit;
  public:
    void receive_unit(const Room& other)
    {
      unit = other.unit;
    }
    void transfer_unit(Room& other)
    {
      other.unit = unit;
    }
};

Вышеупомянутая структура позволяет комнатам общаться друг с другом, ничего не зная о корабле или контейнере .

Примечание. Эти конструкции решают проблему указателя, поскольку указатели не требуются. Вместо этого используются ссылки.

Голосующие против: добавьте пояснения в комментарий.

1
Thomas Matthews 5 Янв 2016 в 20:55