简体   繁体   English

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

[英]C++ Object or 2-dimensional Array as a Parameter?

In a Tic Tac Toe game I creating for school I have five classes: Game (acts as a controller for the game), Player (base class), HumanPlayer and AIPlayer (both derived from Player), and Board. 在我为学校创建的Tic Tac Toe游戏中,我有五个班级:游戏(充当游戏的控制器),玩家(基础班级),HumanPlayer和AIPlayer(均来自玩家)和棋盘。

Board contains a 2D array and some functions for displaying and working on the array. Board包含2D阵列和一些用于显示和处理该阵列的功能。 All three player classes have a function makeAMove(Board &board) which will choose a position on the board and place an X or an O. 所有这三个播放器类都有一个功能makeAMove(Board &board) ,它将在板上选择一个位置并放置X或O。

As you can see makeAMove accepts a Board object as a parameter. 如您所见, makeAMove接受Board对象作为参数。 Then the function will decide on a move and alter the Board object's board array. 然后,该函数将决定移动并更改Board对象的board数组。 If I'm understanding correctly, the actual object being passed in will be altered and there will not be any need to return anything back. 如果我正确理解的话,传入的实际对象将被更改,并且不需要返回任何东西。

Am I understanding this correctly? 我理解正确吗? Would it be better to use the 2d array as the parameter instead? 改用2d数组作为参数会更好吗?

Here is a condensed version of my code. 这是我的代码的精简版。

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

Yes because you're passing the Board object by reference, any change to it in the function will alter the actual Board object. 是的,因为您要通过引用传递Board对象,所以对该函数的任何更改都会更改实际的Board对象。 I think passing a Board object is a better idea, as it is better not to expose the actual implementation ( a 2D array in this case) of the game to the user. 我认为传递一个Board对象是一个更好的主意,因为最好不要向用户公开游戏的实际实现(在这种情况下为2D数组)。 So passing as Board object gives more abstraction, which is good. 因此,将其作为Board对象传递可以提供更多的抽象,这很好。

makeAMove belongs in board . makeAMove属于board The player objects should decide what move to make, then call board::makeAMove to make the move. 玩家对象应该决定要进行的移动,然后调用board::makeAMove进行移动。 That way the player objects don't care what the internal representation of the board is. 这样,玩家对象就不在乎板的内部表示形式。

Pass the object by reference as you are instead of the array. 通过引用按原样传递对象而不是数组。 Any alterations made by the player on the board will persist. 玩家在棋盘上所做的任何更改将继续存在。

board is a private member of Board . board是的私有成员Board It should only ever be returned by value and not by reference. 它只能通过值返回,而不能通过引用返回。 If you pass the 2d array to the player by Value any changes they make to the board will not persist. 如果您通过“值”将2d数组传递给播放器,则他们对面板所做的任何更改都不会保留。

Your Player classes will need to access Board.setCell(int, int) , in the makeAMove(Board &board) function and to do that they will need the board object. 您的Player类将需要访问Board.setCell(int, int) makeAMove(Board &board)函数中的Board.setCell(int, int) ,并且需要使用board对象。

However your Players classes will need to read the board. 但是,您的Players班级将需要阅读董事会。 In order to make a move. 为了出招。 The getCell(int,int) function might be enough but it might also be tedious to nested loop through all of the cells. getCell(int,int)函数可能就足够了,但是嵌套循环遍历所有单元格可能也很getCell(int,int) A getBoard might be useful for a possible decideMove function. getBoard对于可能的decideMove函数可能很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM