C ++ инициализирует 2D примитивный массив в классе значениями из конструктора - PullRequest
0 голосов
/ 02 ноября 2011

Я пытаюсь скомпилировать этот код:

class OthelloState {
public: // constructor 

    Othello(int r, int c);

/* other stuff */

private: // private data

    const int rows;

    const int columns;

    int board[rows][columns];
}

Я заканчиваю с:

OthelloState.h:109: error: invalid use of non-static data member 'OthelloState::rows'
OthelloState.h:115: error: from this location
OthelloState.h:115: error: array bound is not an integer constant
OthelloState.h:112: error: invalid use of non-static data member 'OthelloState::columns'
OthelloState.h:115: error: from this location
OthelloState.h:115: error: array bound is not an integer constant

Я предполагаю, что это означает, что я должен сделать rows и columns статическими. Но если я сделаю их статическими, я не смогу инициализировать их с помощью конструктора, как я должен сделать для этого проекта ...

Есть ли другой способ, которым я могу это сделать?

PS: я знаю, что в реальном Отелло, доска представляет собой квадратную сетку 8 на 8 ... Но, учитывая, сколько времени потребуется компьютеру, чтобы сгенерировать следующий лучший ход на частичной сетке 8 на 8, мы не будет играть с «настоящей» доской Отелло (т.е. без предопределенных размеров досок).

Ответы [ 4 ]

3 голосов
/ 02 ноября 2011

В C ++ массивы переменной длины не допускаются. board[][] необходимо знать оба измерения во время компиляции. Вы можете использовать vector<vector<int> > board;, если хотите инициализировать row и col во время выполнения.

class OthelloState {
public:
    OthelloState(int r, int c);

private: // private data
    const int rows;  // should be 'unsigned int'
    const int columns;

    vector<vector<int> > board;  
};

Другое решение :

Предположим, вы знаете rows и cols во время компиляции, тогда вы можете использовать template. Это так же хорошо, как инициализация row и col в конструкторе.

template<unsigned int row, unsigned int col>
class OthelloState {
public:
...
private:
  int board[row][col];
};

Использование:

  OthelloState<8,8> obj;
  OthelloState<10,10> obj;
0 голосов
/ 02 ноября 2011

Но, учитывая, сколько времени потребуется компьютеру для генерации следующий лучший ход на частичной сетке 8 на 8 мы не собираемся играть с «настоящей» доской Отелло (т.е. без предопределенных размеров платы).

Я понял из этого предложения, что вы работаете над домашним заданием. Если это так, то для вас может оказаться невозможным / нецелесообразным использовать Boost.MultiArray (если только ваш инструктор не посоветовал вам использовать Boost).

Это оставляет vector< vector<int> >, которые являются PITA для правильной инициализации. Прежде чем вы сможете использовать vector< vector<int> >, вы должны пройти через каждый внутренний вектор и изменить его размер.

Boost.MultiArray - это, по сути, просто чрезмерная оболочка для одномерного массива данных. Поэтому я предлагаю третий вариант: сверните свою собственную 2D-оболочку вокруг плоской одномерной vector. Вы можете перегрузить operator(), чтобы имитировать поведение [][] двумерных массивов:

int operator()(size_t row, size_t col) {/*compute index into 1D array*/}

Я разместил пример такой оболочки здесь .

0 голосов
/ 02 ноября 2011

если это всегда 8x8, то константы являются минимальным решением.вот один из способов объявить это:

class OthelloState {
    // ...
private:
    enum { rows = 8, columns = 8 };
    int board[rows][columns];
};
0 голосов
/ 02 ноября 2011

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

class OthelloState {
public: // constructor 

OthelloState(int r, int c)
{ 
   board = new int[r];
   for(int i = 0; i < r; i++)
   {
      board[i] = new int[c];
   }
}


/* other stuff */

private: // private data

   const int rows;

   const int columns;

   int **board;
};

Убедитесь, что у вас есть соответствующие delete s для всех ваших new s в деструкторе, если вы используете этот метод, хотя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...