C ++对象或二维数组作为参数?

时间:2013-12-14 18:59:09

标签: c++ arrays

在我为学校创作的Tic Tac Toe游戏中,我有五个类:游戏(充当游戏的控制者),玩家(基类),HumanPlayer和AIPlayer(均来自玩家)和Board。

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

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

我是否理解正确?使用2d数组作为参数会更好吗?

这是我的代码的精简版本。

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

3 个答案:

答案 0 :(得分:2)

是的,因为您通过引用传递Board对象,函数中对它的任何更改都将改变实际的Board对象。我认为传递Board对象是一个更好的主意,因为最好不要向用户公开游戏的实际实现(在这种情况下是2D数组)。因此,作为Board对象传递会提供更多抽象,这很好。

答案 1 :(得分:1)

makeAMove属于board。玩家对象应决定要移动的内容,然后调用board::makeAMove进行移动。这样,玩家对象就不关心棋盘的内部表现形式了。

答案 2 :(得分:0)

按原样通过引用传递对象而不是数组。玩家在棋盘上所做的任何改动都将持续存在。

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

您的Player课程需要在Board.setCell(int, int)函数中访问makeAMove(Board &board),为此,他们需要电路板对象。

但是,您的Players课程需要阅读电路板。为了采取行动。 getCell(int,int)函数可能已足够,但嵌套循环遍历所有单元格也可能很繁琐。 getBoard可能对decideMove函数有用。