创建指向类的指针的函数

时间:2019-11-13 10:09:00

标签: c++ pointers

我正在尝试创建一个函数,该函数创建指向播放器类实例的指针。

这是因为在游戏开始时,我希望能够制作任意数量的玩家实例。

这将使游戏成为2人,4人或3人游戏,从理论上讲,这是由用户输入确定的无数玩家。

我面临的问题是,如果我使函数创建这样的指针:

编辑:播放器是我创建的用户定义的类。

void createPointer()
{
    player * player1 = new player("George");
}
  1. 将仅在本地声明指针,这会导致内存泄漏,因为我无法引用指针player1,因为一旦函数createPointer()完成,它将被删除。
  2. 如上所示,我将无法正确引用玩家,因为他们都被命名为player1。让我觉得我应该在每次创建播放器时使用c ++中的模板来更改变量的名称。
  3. 如下所示,我无法在游戏结束时删除玩家实例:
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;
}

所以我只是想知道我是否可以采取另一种方法?我知道一种解决方案是预先全局声明指针。即

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

但是,这意味着我不能创建可变数量的玩家,而无需事先声明所有玩家,如上例所示。

抱歉,如果我误解了任何内容,我将不胜感激。

3 个答案:

答案 0 :(得分:5)

如果您真的想为玩家使用原始指针,则可以修改createPointer函数以返回其创建的内容:

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

然后,在要使用此类播放器的代码中,执行以下操作:

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

然后,当您完成播放器的操作后,您只需delete一个即可...

delete player1;
delete player2;

一个更好的解决方案(IMHO)是将createPointer中您最终拥有的任何代码放入player类的 constructor 定义中;那么您可以只使用player *p1 = new player("Harold");之类的代码,而不是每次创建新播放器时都调用一个函数。

但是,如注释中所述,最好使用std::vectorstd::shared_ptr对象。

答案 1 :(得分:5)

您可能需要一个player实例的容器。默认容器为std::vector

类似

std::vector<player> players;

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

您可以根据他们在players中的位置(从0开始)来引用玩家。

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

您可以遍历所有玩家

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

players被销毁后,它会自动清理player个对象

答案 2 :(得分:2)

如果我对您的理解正确,也许有两种解决方案可以解决您的问题。 这里是代码。

#include <string>
#include <iostream>
using namespace std;


class Player
{
public:
    Player(string name) :m_name(name) {
        cout << "player " << m_name << " is created\n";
    }
    ~Player()
    {
        cout << "pluaer " << m_name << " is destoryed\n";
    }
private:
    string m_name;
};

//The first solution : return a pointer
Player* creatPlayer_1(const string& name)
{
    return new Player(name);
}

//The second solution : pass a reference of the pointer as the argument
void createPlayer_2(Player*& pPlayer, const string& name)
{
    pPlayer = new Player(name);
}

int main()
{
    Player* pPlayer_one = creatPlayer_1("one");

    Player* pPlayer_two = nullptr;
    createPlayer_2(pPlayer_two, "two");

    delete pPlayer_one;
    delete pPlayer_two;
}