【问题标题】:C++ Object or 2-dimensional Array as a Parameter?C++ 对象或二维数组作为参数?
【发布时间】:2013-12-14 18:59:08
【问题描述】:

在我为学校创建的井字游戏中,我有五个类:Game(充当游戏的控制器)、Player(基类)、HumanPlayer 和 AIPlayer(均源自 Player)和 Board。

Board 包含一个二维数组和一些用于显示和处理数组的函数。所有三个玩家类别都有一个函数makeAMove(Board &board),它将在棋盘上选择一个位置并放置一个 X 或一个 O。

如您所见,makeAMove 接受 Board 对象作为参数。然后该函数将决定移动并更改 Board 对象的 board 数组。如果我理解正确,传入的实际对象将被更改,并且不需要返回任何东西。

我理解正确吗?用二维数组作为参数会更好吗?

这是我的代码的精简版。

#include <iostream>
#include <memory> // auto_ptr

class Board
{
    public:
        Board()
        {
            for (int row = 0; row < 3; row++)
            {
                for (int column = 0; column < 3; column++)
                    board[row][column] = ' ';
            }
        }

        void displayBoard()
        {
            std::cout << "\n-------------" << std::endl;

            for (int row = 0; row < 3; row++)
            {
                std::cout << "| " ;
                for (int column = 0; column < 3; column++)
                    std::cout << board[row][column] << " | ";
                std::cout << "\n-------------" << std::endl;
            }
        }

/*      My thought was to use getBoard to return the array rather than using the 
        object as a parameter       
        char getBoard()
        {
            return board[][3];
        }       
*/

    char getCell(int row, int column)
    {
        return board[row][column];
    }

    void setCell(int row, int column, char player)
    {
        board[row][column] = player;
    }

    private:
        char board[3][3];

};

class Player
{
    public:
        virtual void makeAMove(Board &board) = 0;   
};

class AIPlayer : public Player
{
    virtual void makeAMove(Board &board)
    {
        // do some work ont the board array
    }   
};

class HumanPlayer : public Player
{
    virtual void makeAMove(Board &board)
    {
        // do some work on the board array
    }
};

class Game 
{
    public: 
        Game(unsigned int players)
        {
            if (players == 1)
            {
                player1.reset (new HumanPlayer()); 
                player2.reset (new AIPlayer());
            }
            else 
            {
                player1.reset (new HumanPlayer());
                player2.reset (new HumanPlayer());
            }
        }

        void playGame()
        {
            player1->makeAMove(myBoard);
        }

    private:
        std::auto_ptr<Player> player1; // pointer to a Player object (C++11 has more secure unique_ptr)
        std::auto_ptr<Player> player2; // pointer to a Player object
        Board myBoard;
};

int main() 
{
    Game myGame(1);
    myGame.playGame();

    return 0;
}

【问题讨论】:

    标签: c++ arrays


    【解决方案1】:

    是的,因为您通过引用传递 Board 对象,因此函数中对其进行的任何更改都会改变实际的 Board 对象。我认为传递Board 对象是一个更好的主意,因为最好不要将游戏的实际实现(在本例中为二维数组)暴露给用户。所以作为 Board 对象传递给了更多的抽象,这很好。

    【讨论】:

      【解决方案2】:

      makeAMove 属于board。玩家对象应该决定采取什么行动,然后调用board::makeAMove 进行行动。这样玩家对象就不会关心棋盘的内部表示是什么。

      【讨论】:

        【解决方案3】:

        通过引用而不是数组传递对象。棋盘上的玩家所做的任何更改都将保留。

        boardBoard 的私有成员。它应该只按值返回,而不是按引用返回。如果您通过 Value 将 2d 数组传递给玩家,他们对棋盘所做的任何更改都不会保留。

        您的Player 类将需要在makeAMove(Board &amp;board) 函数中访问Board.setCell(int, int),并且为此他们需要板对象。

        但是,您的Players 课程需要阅读黑板。为了出手。 getCell(int,int) 函数可能就足够了,但嵌套循环遍历所有单元格也可能很乏味。 getBoard 可能对可能的 decideMove 函数有用。

        【讨论】:

        • 是的,你可能是对的。但我不确定如何在 getter 中返回二维数组。
        • 你真的不应该,除非数组是来自 c++11 的 std::vector&lt;std::vector&gt;std::array&lt;std::array&gt;。否则你的玩家将不知道数组的长度。也许只有char[9] 而不是二维数组?真的需要二维数组吗?
        • 不,它没有。它只是使用户输入更容易。用户将首先输入一行,然后输入一列。然后将这些数字直接应用于二维数组(经过一些验证)。如果我使用一维数组,我需要将每一行和每一列转换为一个索引。当然不是不可能,但我会尽量保持简单。
        • 用户输入rowcol。索引为(row*3 - 1) + (col -1) 或反之亦然,具体取决于您如何索引一维数组。 IMO 这比循环出二维数组要简单得多。如果你使用它,那条线将进入setCell
        • 我不确定我明白它是如何工作的。如果用户输入第 1 行和第 1 列,则转换为 2 + 0 = 2。
        猜你喜欢
        • 1970-01-01
        • 2019-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-19
        相关资源
        最近更新 更多