简体   繁体   中英

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.

Board contains a 2D array and some functions for displaying and working on the array. 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.

As you can see makeAMove accepts a Board object as a parameter. Then the function will decide on a move and alter the Board object's board array. 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?

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. 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. So passing as Board object gives more abstraction, which is good.

makeAMove belongs in board . The player objects should decide what move to make, then call board::makeAMove to make the move. 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 . 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.

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.

However your Players classes will need to read the board. 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. A getBoard might be useful for a possible decideMove function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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