井字棋开发:如何基于类中const成员变量动态声明二维数组
动态创建匹配尺寸的二维棋盘方案
嘿,这个问题我太熟悉了!在C++里处理由运行时用户输入确定尺寸的二维数组(比如你的井字棋棋盘),结合你已经在构造函数中初始化了const int m_width和const int m_height的情况,这里有几种实用且贴合场景的方案:
方案1:用std::vector二维容器(最推荐)
这是现代C++里最省心的方式,完全不用手动管理内存,安全又易维护,特别适合游戏开发场景。
步骤:
- 在类中声明二维vector成员:
class TicTacToe { private: const int m_width; const int m_height; std::vector<std::vector<char>> m_board; // 用char存X/O或空字符 public: TicTacToe(int width, int height) : m_width(width), m_height(height) { // 初始化棋盘:m_height行,每行m_width个元素,初始化为空格 m_board = std::vector<std::vector<char>>(m_height, std::vector<char>(m_width, ' ')); } // 其他成员函数... };
- 访问棋盘元素直接用
m_board[row][col]就行,比如落子操作:
void placePiece(int row, int col, char piece) { if (row >= 0 && row < m_height && col >=0 && col < m_width) { m_board[row][col] = piece; } }
这种方案的优势是:自动处理内存释放,支持拷贝/赋值操作(vector自带深拷贝),还能灵活调整大小(虽然你井字棋可能不需要,但留有余地)。
方案2:原生动态分配数组(需手动管理内存)
如果你偏好原生数组,也可以用new来动态创建,但一定要记得在析构函数中释放内存,避免泄漏。
步骤:
- 在类中声明指针成员:
class TicTacToe { private: const int m_width; const int m_height; char** m_board; public: TicTacToe(int width, int height) : m_width(width), m_height(height) { // 先分配行 m_board = new char*[m_height]; // 再分配每行的列 for (int i = 0; i < m_height; ++i) { m_board[i] = new char[m_width]; // 初始化每行元素为空格 std::fill(m_board[i], m_board[i] + m_width, ' '); } } // 必须写析构函数释放内存 ~TicTacToe() { // 先释放每行的列 for (int i = 0; i < m_height; ++i) { delete[] m_board[i]; } // 再释放行 delete[] m_board; } // 注意:如果需要支持拷贝构造和赋值运算符,必须自己实现深拷贝,否则会有浅拷贝问题 TicTacToe(const TicTacToe& other) = delete; // 或者手动实现深拷贝 TicTacToe& operator=(const TicTacToe& other) = delete; };
这种方式的缺点是需要手动管理内存,容易出错,而且拷贝逻辑需要额外处理,所以除非有特殊需求,否则更推荐方案1。
方案3:用智能指针管理动态数组(折中方案)
如果想避免手动delete,又想用原生数组的形式,可以用std::unique_ptr来自动管理内存:
class TicTacToe { private: const int m_width; const int m_height; std::unique_ptr<std::unique_ptr<char[]>[]> m_board; public: TicTacToe(int width, int height) : m_width(width), m_height(height) { m_board = std::make_unique<std::unique_ptr<char[]>[]>(m_height); for (int i = 0; i < m_height; ++i) { m_board[i] = std::make_unique<char[]>(m_width); std::fill(m_board[i].get(), m_board[i].get() + m_width, ' '); } } // 不需要手动写析构函数,unique_ptr会自动释放内存 };
这种方式比原生new安全,但代码复杂度比vector高,所以还是优先选vector。
内容的提问来源于stack exchange,提问作者Ilir Hajrullahu
相关产品推荐
相关产品推荐

