c++用构造函数的值初始化类中的二维原始数组

C++ initialize a 2D primitive array in a class with values from a constructor

本文关键字:二维 原始 数组 构造函数 初始化 c++      更新时间:2023-10-16

我正在尝试编译这段代码:

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的网格上生成下一个最佳移动需要多长时间之后,我们不打算玩"真正的"奥赛罗棋盘(即没有预定义的棋盘大小)。

在c++中,可变长度数组是不允许的。board[][]在编译时需要知道它的两个维度。如果你想在运行时初始化rowcol,你可以使用vector<vector<int> > board;

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;

如果总是8x8,则常数是最小解。下面是声明它的一种方法:

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

但是考虑到计算机需要多长时间才能生成在部分8乘8的格子里,下一个最好的棋,我们就不玩了使用"真正的"奥赛罗板(即没有预定义的板大小)。

我从那句话推断出你在做家庭作业。如果是这种情况,那么您可能不可能/不实际地使用Boost。MultiArray(除非你的老师建议你可以使用Boost)。

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

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

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

我在这里贴了一个这种包装器的例子

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

相同的名称。
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;
};

如果使用此方法,请确保在析构函数中为所有new设置匹配的delete s,但是