创建一个类的二维数组

3

嗨,如果有人能指导我如何正确地做到这一点。基本上,我正在尝试创建一个名为Board的类变量,其中包含棋子实例的二维数组。

#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;

class ChessPiece
{
public:
    char ToChar() { return '#'; };
};

class ChessBoard
{
    int Size;   //This means board is 8x8.
    ChessPiece ** Board;

public:
    ChessBoard();
    int GetSize() { return Size; };

    void PlotBoard();
};

ChessBoard::ChessBoard() {
    Size = 8;
    ChessPiece newBoard[Size][Size];
    Board = newBoard; //Problem here!!! How do I make Board an 8x8 array of ChessPiece?
}

void ChessBoard::PlotBoard() {
    int x, y;
    for (x = 0; x < Size; x++) {
        for (y = 0; y < Size; y++)
            printf("%c", Board[x][y].ToChar());
    }
}

int main()
{
    // ChessBoard board;
    // printf("%d", board.GetSize());
    // board.PlotBoard();

    ChessBoard * a = new ChessBoard();

    return 0;
}

这其实是一个非常基础的问题,但我似乎无法弄清楚。

谢谢!


4
可以将std::vector<std::vector<ChessPiece>>简化为更简单的std::vector<ChessPiece>,并使用简单的乘法来跟踪行/列的索引。 - Chad
我会像@Chad一样去做。我个人会使用第二个版本,但这不重要。 - keyser
程序是否只需要支持标准的8x8棋盘,还是您想要能够在除了8x8之外的任意大小的棋盘上玩耍?如果您只需要标准的8x8棋盘,那么您可以将尺寸设置为常量,然后只使用简单的8x8固定大小的二维数组。 - Jeremy Friesner
5个回答

2

在您的情况下,没有使用裸指针的必要。我建议将棋盘作为单维std::vector进行存储,并在迭代棋盘时仅使用行/列的乘法。

class ChessBoard
{
public:
   ChessBoard(size_t row_count) : Size(row_count), Board(row_count * row_count)
   {
   }

   void PlotBoard()
   {
     for(size_t row = 0; row < Size; ++row)
     {
        for(size_t col = 0; col < Size; ++col)
            printf("%c", Board[(row * Size) + col].ToChar());
     }
   }
}

private:
   size_t Size;
   std::vector<ChessPiece> Board;
};

你肯定是想说 Board[row * Size + col],对吧? - anatolyg

1

将您的构造函数更改为:

ChessBoard::ChessBoard():Size(8) {
    Board=new ChessPiece*[Size];

    for (int i=0;i<Size;++i)
        Board[i]=new ChessPiece[Size];
}

你还需要一个析构函数:
ChessBoard::~ChessBoard()
{
    for (int i=0;i<Size;++i)
        delete [] Board[i];

    delete [] Board;
}

如果你想允许复制/移动,请确保添加适当的复制/移动构造函数和复制/移动赋值运算符。


1
class ChessBoard {
    public:
    enum Field {
       Empty,
       Pawn,
       ...
    };
    const Columns = 8;
    const Rows = 8;
    Field& operator()(unsigned column, unsigned row) { 
        return fields(column * Rows + row);
    } // omitting const/non const and range checks

    private:
    Field fields[Columns * Rows];
};

0
去年我做过类似的项目。我创建了一个Square类,这样一个Board就由一个二维数组的Squares组成。我认为这样你会更有灵活性,因为你可以为Square创建方法,比如检查Square上是否有Piece(它自己的类),Piece的类型是什么,以及添加和删除Pieces。
我认为你需要用基本的OO方式来解决这个问题。

-1
问题在于 newBoard 被创建为自动储存期,这意味着当你超出作用域时它会被清除(在 ChessBoard 构造函数的末尾)。如果 Size 永远不会改变,你可以将它设置为常量,并像这样创建棋盘:
#define SIZE 8
class ChessBoard
{
    ChessPiece Board[SIZE][SIZE];

如果大小可能会改变,您需要像这样在循环中分配数组:
Board = new ChessPiece *[Size];
for (int i = 0; i < Size; i++){
    Board[i] = new ChessPiece[Size];
}

-1:使用new是低效且容易出错的。 (考虑使用std::vector,已在另一个答案中推荐)此外,您的答案中没有提及如何释放内存。 - milleniumbug

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接