Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function that creates pointers to classes

Tags:

c++

pointers

I'm trying to create a function that creates pointers to instances of a player class.

This is because, at the start of my game, I want to be able to make as many player instances as I want.

This is to make the game 2-player, 4-player or 3-player and theoretically, an infinite number of players determined by the user's input.

The problem I'm facing is that if I make my function to make pointers like this:

edit: player is a user defined class that I made.

void createPointer()
{
    player * player1 = new player("George");
}
  1. The pointer will only be locally declared, resulting in a memory leak, because I can't reference the pointer player1, as it's deleted once the function createPointer() concludes.
  2. I wouldn't be able to reference the players correctly, as shown above, as they're all named player1. Makes me think I should use templates in c++ to change the name of the variable each time a player is created.
  3. As shown below, I couldn't delete the player instance at the end of the game:
void endGame()
{
    //delete the object the pointer
    //is pointing to in memory
    delete player1;
    //set the pointer to point to NULL
    //as default, so can check if pointer is pointing
    //to anything
    player1 = NULL;
}

So I was just wondering if there was another approach I could take? I know of one solution which is to globally declare the pointers beforehand. i.e

player * player1 = NULL;
player * player2 = NULL;
player * player3 = NULL;
void createPointer()
{
    player1 = new player("George");
}

However, this would mean I cannot create a variable number of players without declaring all of them beforehand, as shown in the above example.

Apologies if I am misunderstanding anything, I would highly appreciate any advice whatsoever.

like image 749
George Smith Avatar asked Nov 13 '19 10:11

George Smith


2 Answers

If you really want to use raw pointers for your players, you can modify your createPointer function to return what it has created:

player* createPointer()
{
    player* createdPlayer = new player("George");
    // Do whatever you need for initialization!
    return createdPlayer;
}

Then, in the code that wants to use such players, do something like:

//...
player* player1 = createPointer();
player* player2 = createPointer();
//...

Then, when you've done with the players, you can just delete each one...

delete player1;
delete player2;

A better solution (IMHO) would be to put whatever code you (eventually) have in createPointer into the constructor definition for the player class; then you can just use code like player *p1 = new player("Harold"); rather than calling a function each time you make a new player.

But, as mentioned in the comments, you would be better off using either std::vector or std::shared_ptr objects.

like image 102
Adrian Mole Avatar answered Sep 25 '22 02:09

Adrian Mole


You probably need a container of player instances. The default container is std::vector.

Something like

std::vector<player> players;

players.emplace_back("George"); // Create the first player
players.emplace_back("Fred"); // Create the next player
// etc.

You can refer to players by their (0 based) position in players

players[0].do_stuff(); // George does stuff

You can loop over all the players

for (auto & player : players) {
    player.take_turn(); // each player in turn does something
}

When players is destroyed, it automatically cleans up the player objects

like image 20
Caleth Avatar answered Sep 22 '22 02:09

Caleth