C ++使用构造函数中的值初始化类中的2D基元数组

时间:2011-11-02 02:43:07

标签: c++ class compilation multidimensional-array

我正在尝试编译此代码:

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

我认为这意味着我必须将rowscolumns设为静态。但是,如果我将它们设置为静态,我无法使用构造函数进行初始化,这是我为此项目所必需的方式......

我还有其他方法吗?

PS:我知道在真正的奥赛罗,主板是一个8×8格的方块......但是考虑到计算机需要多长时间才能在8×8网格上产生下一个最好的移动,我们是不打算使用“真正的”奥赛罗板(即没有预定义的板尺寸)。

4 个答案:

答案 0 :(得分:3)

在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;  
};

其他解决方案

假设您在编译时知道rowscols,那么您可以使用template。这与在构造函数中初始化rowcol一样好。

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

用法:

  OthelloState<8,8> obj;
  OthelloState<10,10> obj;

答案 1 :(得分:0)

您正尝试在运行时动态定义编译时固定大小数组的大小。您需要动态分配内存。您还需要您的构造函数与您的类具有相同的名称

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匹配new,但

答案 2 :(得分:0)

如果它总是8x8,那么常数是最小的解决方案。这是宣告它的一种方式:

class OthelloState {
    // ...
private:
    enum { rows = 8, columns = 8 };
    int board[rows][columns];
};

答案 3 :(得分:0)

  

但是在考虑计算机生成需要多长时间之后   对于8×8网格的下一个最佳移动,我们不打算玩   与“真正的”奥赛罗板(即没有预定义的板尺寸)。

我从那句话中推断出你正在做家庭作业。如果是这种情况,那么使用Boost.MultiArray可能不可行/不实用(除非你的导师告诉你可以使用Boost)。

留下vector< vector<int> >这是一个正确初始化的PITA。在你甚至可以使用vector< vector<int> >之前,你必须遍历每个内部向量并调整它的大小。

Boost.MultiArray基本上只是围绕一维数据数据的过度包装。因此,我提出了第三种选择:在平面一维vector周围卷起自己的2D包装器。您可以重载operator()以模仿2D数组的[][]行为:

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

我发布了这种包装器here的示例。