【问题标题】:C++ Vector item being deleted after push_back()在 push_back() 之后被删除的 C++ 向量项
【发布时间】:2016-01-09 00:56:53
【问题描述】:

我在将对象推送到向量时遇到问题。

我涉及三个类:Pack.h、Player.h、Hand.h

Pack 发牌,Player 接受 Pack 的牌,然后 Hand 接受 Player 的牌。

功能:

发牌的包

bool Pack::Deal(std::vector<Player>players, unsigned int numberOfCards)
{
    //This assumes that if we cannot deal the requested number of cards we do not deal any cards at all.
    //If we wanted to deal as many cards as possibly we would check for errors while iterating over players.

    if (m_pack_of_cards.size() < players.size() * numberOfCards) //check that we have enough cards to complete deal
    {
        std::cout << "Not enough cards to complete deal." << std::endl;
        return false;
    }
    else
    {
        for (unsigned int i = 0; i < numberOfCards; i++)
        {
            for (auto player : players)
            {
                player.Accept_Card_From_Pack(m_pack_of_cards.back());
                m_pack_of_cards.pop_back();
            }
        }
        return true;
    }
}

玩家从包中接受卡片

bool Player::Accept_Card_From_Pack(Card card)
{
    m_player_hand.Accept_Card_From_Player(card);
    return true;
}

从玩家手中接过卡片的手

bool Hand::Accept_Card_From_Player(Card card)
{   
    m_hand_of_cards.push_back(card);
    return true;
}

我的主要功能

int main()
{
    Pack pack = Pack();
    std::vector<Player> players(4);
    for (int i = 0; i < 4; i++)
    {
        players[i] = Player("Player: " + std::to_string(i));
    }

    pack.Deal(players, 8);

    system("pause");
    return 0;
}

它的作用是创建一个新包,创建一些玩家,向每个玩家发一些牌。

问题出在玩家拿牌,Pack 调用玩家接受卡片函数,玩家接受卡片函数调用 Hand 的接受卡片函数,然后 Hand 应该将卡片推回它的卡片向量。

它确实将其推回,如果我在 push_back 之前和之后 std::cout 向量的大小从 0 变为 1,但它并没有保留该项目,所以下次我推回它时将再次给我 0 和 1 作为 push_back 前后向量的大小。

哦,这是大学作业(我必须把它放在这里吗?我不记得了)。

【问题讨论】:

    标签: c++ vector


    【解决方案1】:

    找出问题所在,这通常发生在我发布问题后,但如果有人遇到类似问题,我会在这里回答。

    问题出在 Player Deal 函数的这一点上:

    for (auto player : players)
            {
                player.Accept_Card_From_Pack(m_pack_of_cards.back());
                m_pack_of_cards.pop_back();
            }
    

    应该是:

    for (auto &player : players)
                {
                    player.Accept_Card_From_Pack(m_pack_of_cards.back());
                    m_pack_of_cards.pop_back();
                }
    

    正如下面提到的Eelke和Underscore_d,也应该传递参数:

    std::vector<Player>players 
    

    作为

    std::vector<Player>&players
    

    【讨论】:

    • 我还是想说,通常的建议是通过引用处理所有传递/迭代的对象(非原始类型)。它避免了围绕复制/更改对象的各种混淆,例如这个。
    • 您还应该通过引用 deal 函数来传递玩家向量。
    • 很高兴你把它整理好了。 Imo 您的默认位置应该是使用引用,除非您有特定需要使用副本(按值隐式创建)。人们通常从这条规则中排除原始类型的函数参数,例如因为通过引用传递它们通常效率较低(指针大小/取消引用权衡),而且我认为这些函数不经常被函数更改。
    • @underscore_d:为了避免混淆,这都是关于参数传递的。返回值完全是另一回事。
    • 好点。我最初提到了这些,但在我随后的评论中没有提到,因为它们不相关,但值得指出的是,它们没有遵循与参数相同的准则——在许多情况下是迭代器。下次我会尝试这样做。
    猜你喜欢
    • 2016-04-14
    • 2016-11-16
    • 2011-06-09
    • 1970-01-01
    • 2023-04-06
    • 2022-01-22
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多