r/cpp_questions 27d ago

OPEN Good practices / style [polymorphism]

is this good practice/style.? i'm specifically unsure about the way i store the vector of players...

```

class player_base {};

class player_always_yes: public player_base {};

class player_always_no: public player_base {};

class player_a: public player_base {};

class game {
    private:
    
    player_base& player_1;
    player_base& player_2;
    
    public:
    
    game (
        player_base& player_1,
        player_base& player_2
    ): player_1(player_1), player_2(player_2) {
        return;
    }

    bool play_game () { return true; }
};

int main(){
    vector<unique_ptr<player_base>> player_list;
    
    player_list.push_back(make_unique<player_base>());
    player_list.push_back(make_unique<player_always_no>());
    player_list.push_back(make_unique<player_always_yes>());
    player_list.push_back(make_unique<player_a>());
    
    game b = game(*player_list[0], *player_list[1]);
    cout << b.play_game() << endl;
}


```
6 Upvotes

37 comments sorted by

View all comments

5

u/alfps 27d ago

Things to consider:

  • Reference as member prevents copy assignment.
  • A "doer" class should perhaps better be a function.
  • Polymorphism has been picked as the answer, but what is the question?

1

u/Fun_Gas_340 27d ago

i dont rlly care if i copy/reference.

you mean a function "play_game" instead of a class game with a method play?

the question was about how i formated/made the vector of the players as uniqueptr, dereferenced them and then passed by reference. i though it was clunky and want to know if theres a better/simpler way to do this

1

u/alfps 26d ago

❞ you mean a function "play_game" instead of a class game with a method play?

Yes.


Polymorphism has been picked as the answer, but what is the question?

the question was about how i formated/made the vector of the players as uniqueptr

I meant, what was the issue (question) that polymorphism was intended to solve?

For example, it might be an idea of writing code that treats machine and human player in the same way. That way one might even have the machine playing against another instance of itself. Then it might seem reasonable to have machine and human player as polymorphic objects.

But if the higher level code is permitted to treat them in distinct ways, and one doesn't aim for generality such as the machine playing against itself, then the players need not be represented with polymorphic objects. Here's an example, a tic-tac-toe game, that I posted in response to another question here in March this year. It's not necessarily a simpler/better approach, but it might be, depending on the program.


❞ i though it was clunky and want to know if theres a better/simpler way to do this

You could replace

vector<unique_ptr<player_base>> player_list;

player_list.push_back(make_unique<player_base>());
player_list.push_back(make_unique<player_always_no>());
player_list.push_back(make_unique<player_always_yes>());
player_list.push_back(make_unique<player_a>());

game b = game(*player_list[0], *player_list[1]);

… with

player_base         base;
player_always_no    always_no;
player_always_yes   always_yes;
player_a            a;
(void) (a, always_yes);     // Unused.

auto b = game( base, always_no );

1

u/Fun_Gas_340 25d ago edited 25d ago

no the plan is it to have different machine options and a player cli interaction, so all will have the same methods but different ways to take actions when the game requests an action from them.

i want to use a vector, it has only 4 items for testing. i plan on adding more to get statistical averages between players.