【问题标题】:Creating two dimensional array of class创建类的二维数组
【发布时间】:2013-08-13 18:56:47
【问题描述】:

您好,如果有人可以建议如何正确执行此操作。基本上,我正在尝试创建一个名为 Board 的类变量,其中包含 ChessPiece 实例的二维数组。

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

我在这里确实缺少非常基本的东西,但我似乎无法弄清楚。 谢谢!

【问题讨论】:

  • std::vector&lt;std::vector&lt;ChessPiece&gt;&gt;,或者更简单的std::vector&lt;ChessPiece&gt;,并使用简单的乘法将索引作为行/列进行跟踪。
  • 我会像@Chad 那样做。我自己会使用第二个版本,但这并不重要。
  • 程序是否只需要支持标准的 8x8 棋盘,或者您是否也希望能够在 8x8 以外的任意大小的棋盘上玩?如果只需要标准的 8x8,不妨将 Size 设为常量,然后使用简单的 8x8 固定大小二维数组即可。

标签: c++ arrays class


【解决方案1】:

确实没有理由在您的场景中使用原始指针。我建议将板子保持为一维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],不是吗?
【解决方案2】:
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];
};

【讨论】:

    【解决方案3】:

    将您的构造函数更改为:

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

    如果要允许复制/移动,请务必添加正确的复制/移动构造函数和复制/移动赋值运算符。

    【讨论】:

      【解决方案4】:

      我去年做了一个类似的项目。为此,我创建了一个 Square 类,以便 Board 由 Squares 的二维数组组成。我认为通过这种方式你可以更灵活地为 Square 创建方法,例如检查 Square 上是否有 Piece(它自己的类)、什么类型的 Piece 以及添加和删除 Pieces。

      我认为您需要以基本的 OO 方式来解决问题。

      【讨论】:

        【解决方案5】:

        这里的问题是 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,已经在另一个答案中推荐过)另外,你没有在你的答案中提到如何释放内存。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-27
        • 2012-03-23
        • 2011-10-19
        • 1970-01-01
        • 1970-01-01
        • 2021-04-28
        相关资源
        最近更新 更多