2

I'm having a little problem where I want two different classes to be able to share and make changes to another class object.

I've got a HumanPlayer class, a ComputerPlayer class, and a Board class. The two player classes need to be able to interact with the one Board class. I thought that I could pass a reference to the same Board object to each class but it doesn't appear to be working the way I want it to. Here's part of what's in main and I'll describe what's happening as best I can:

//main.cpp

    Board *board2 = new Board();
    board2->setBoardSize(5); 
    board2->initPits(); 

    HumanPlayer firstPlayer(*board2, *menu, menu->askForFirstTurn(), true); 

    firstPlayer.removeFromPit(3);  

    board2->showBoard();

firstPlayer.removeFromPit(3); is supposed to just set a value in an array in the board class to zero. And it does that. If I were to show the board from within the code of the FirstPlayer class, it would show the change. But when I call board2->showBoard() it's as if nothing was changed. It's still the original unchanged board. What I really want to have happen is to have my firstPlayer and secondPlayer classes work on one shared board object. I'm just not sure how to implement this properly now.

Thank you all for your help. Let me know if you need more information.

5
  • HumanPlayer firstPlayer(*board2, *menu, menu->askForFirstTurn(), true); is undefined behavior. Commented Sep 17, 2011 at 20:45
  • @Marlon: How so? It looks fine to me. Commented Sep 17, 2011 at 20:48
  • The code you posted looks ok to me. It ought to do exactly what you described. So the problem is probably how removeFromPit() is implemented. Or maybe how you store board reference inside HumanPlayer class. Commented Sep 17, 2011 at 20:48
  • @Marlon -- can you state what you mean? That statement alone looks fine to me. d2jxp--- Show the constructor(s) of your board and player classes. Commented Sep 17, 2011 at 20:51
  • Well I suppose I could be wrong (in which case I will delete my first comment.) But imagine this: HumanPlayer firstPlayer(*board2, i, ++i, true); if askForFirstTurn changes the state of the object, and *menu is passed by value, then behavior could be undefined. Commented Sep 17, 2011 at 20:53

4 Answers 4

3

It sounds like you are copying the board object instead of passing it by reference. The constructor of your player classes should look like this:

class Player
{
public:
    Player(Board& board) // REFERENCE TO Board
       : the_board_(board) // initialize the reference
    {
    }

protected:
   Board& the_board_;  // REFERENCE to Board
};

If you are missing the & operator anywhere (either in the constructor signature or on the class member variable) then you will make a copy of the board that will be used within your class.

Sign up to request clarification or add additional context in comments.

Comments

1

HumanPlayer firstPlayer(*board2, *menu, menu->askForFirstTurn(), true);

you pass the 1st parameter by a value. Remove * and add it to the declaration of firstPlayer function

2 Comments

That would pass the board by pointer, not by reference. Passing by reference this would be OK if the constructor(s) of the classes accepting it are written properly.
what is wrong about passing a parameter by pointer? Works fine regardless classes constructor
1

You are probably not using a reference all the way through. There are two things to check:

  1. HumanPlayer's constructor must take the board as a reference (Board&). Check that Board& is the type of the parameter. Otherwise when you call the constructor you are implicitly making a copy of the Board so that the constructor can take the Board by value.

  2. The type of HumanPlayer's member variable for the board must be Board& as well. Otherwise when you set the member variable you are implicitly copying the data from the original Board object. Keep in mind that when using a reference as a member variable that you need to use the constructor initializer list rather than assignment.

Comments

1

My best guess would be that your declaration of HumanPlayer's constructor looks something like:

HumanPlayer( Board board, Menu menu, int askForTurn, int otherBoolean );

so when you call it with

HumanPlayer firstPlayer(*board2, *menu, menu->askForFirstTurn(), true);

you actually have firstPlayer initialize using a copy of board2 rather than a reference to it.

If this is indeed what your code looks like, you need to make sure that HumanPlayer's constructor is declared to receive a reference to board (and probably menu?). That would look like:

HumanPlayer( Board& board, Menu& menu, int askForTurn, int otherBoolean );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.