C++ 删除其引用在三个不同列表中维护的指针对象

C++ 删除其引用在三个不同列表中维护的指针对象,c++,memory,memory-management,pointers,garbage-collection,C++,Memory,Memory Management,Pointers,Garbage Collection,我不知道如何解决这个问题: “Player”类维护Bullet*对象的列表: class Player { protected: std::list< Bullet* > m_pBullet_list; } 另外,我读到了,它提到它调用了我们试图删除的对象的析构函数。根据这些信息,如果我从一个列表中删除对象,则该对象不存在,但该列表仍将包含对该对象的引用。如何处理所有这些问题?一个选项是对弱引用使用引用计数(Boost支持这一点)。您有一个拥有强引用的“权威”容器,因此

我不知道如何解决这个问题:

“Player”类维护Bullet*对象的列表:

class Player
{
protected:
    std::list< Bullet* > m_pBullet_list;
}



另外,我读到了,它提到它调用了我们试图删除的对象的析构函数。根据这些信息,如果我从一个列表中删除对象,则该对象不存在,但该列表仍将包含对该对象的引用。如何处理所有这些问题?

一个选项是对弱引用使用引用计数(Boost支持这一点)。您有一个拥有强引用的“权威”容器,因此会删除从中删除的任何项目符号。所有其他容器都使用弱引用,并在发现弱引用无效时删除项目符号


这确实会在一些地方使事情稍微复杂化,但它在逻辑上比其他机制更干净、更安全。

一个选项是使用弱引用的引用计数(Boost支持这一点)。您有一个拥有强引用的“权威”容器,因此会删除从中删除的任何项目符号。所有其他容器都使用弱引用,并在发现弱引用无效时删除项目符号


这确实会在一些地方使事情稍微复杂化,但它在逻辑上比其他机制更干净、更安全。

有趣的观察,或者这只是“未定义行为”的一部分。所以,这就是我如何扔掉一颗子弹,而它并没有给我一个错误。到目前为止:

void CollisionMgr::TrashBullet(Bullet* a_pBullet, Cell* a_pCell)
{

    a_pBullet->Owner()->TrashBullet( a_pBullet );
    m_BulletPList.remove( a_pBullet );
    //a_pCell->m_BulletPList.remove( a_pBullet );

    delete a_pBullet;
}

所以,一旦我从列表中“删除”了对Bullet的引用,我就会手动删除它。让我困惑的是,从“list::remove”的描述中可以看出:

void remove(const T&value)
删除具有特定值的元素。
从列表中删除所有元素
具有特定的值。这就叫
这些对象的析构函数和
将列表大小减少
删除元素

因此,当我从列表中调用remove on bullet时,应该调用该bullet对象的析构函数。但是,这不会发生在这里。。。
那么,这只是未定义行为和我的编译器的怪癖的一部分,还是我遗漏了一些琐碎的东西?

有趣的观察,或者这只是“未定义行为”的一部分。所以,这就是我如何扔掉一颗子弹,而它并没有给我一个错误。到目前为止:

void CollisionMgr::TrashBullet(Bullet* a_pBullet, Cell* a_pCell)
{

    a_pBullet->Owner()->TrashBullet( a_pBullet );
    m_BulletPList.remove( a_pBullet );
    //a_pCell->m_BulletPList.remove( a_pBullet );

    delete a_pBullet;
}

所以,一旦我从列表中“删除”了对Bullet的引用,我就会手动删除它。让我困惑的是,从“list::remove”的描述中可以看出:

void remove(const T&value)
删除具有特定值的元素。
从列表中删除所有元素
具有特定的值。这就叫
这些对象的析构函数和
将列表大小减少
删除元素

因此,当我从列表中调用remove on bullet时,应该调用该bullet对象的析构函数。但是,这不会发生在这里。。。
那么,这只是未定义行为和我的编译器的怪癖的一部分,还是我遗漏了一些琐碎的东西?

您在这些列表中存储的不是项目符号,而是指向项目符号的指针,因此不会调用析构函数。可以安全地从所有列表中删除对象,但您需要调用delete yourself。

这些列表中不存储项目符号,而是指向项目符号的指针,因此不会调用析构函数。这些对象可以安全地从所有列表中删除,但您需要自己调用delete。

我有点理解,但您能更具体一点吗?什么是搜索的好关键字?看看Boost。我有点理解,但你能更具体一点吗?什么是搜索的好关键字?看看Boost。不,不应该调用析构函数。您正在从列表中删除指向项目符号的指针。对象有析构函数,指针没有。如果指针指向动态分配的对象,则您有责任调用delete-但只能在其中一个指针上调用delete。容器中包含的指针将被析构函数,这是您提供的引号所指示的。指针指向的对象不会自动销毁。您必须在指针上准确地调用deleted一次。更简单的方法是使用某种智能指针来管理它。不,不应该调用析构函数。您正在从列表中删除指向项目符号的指针。对象有析构函数,指针没有。如果指针指向动态分配的对象,则您有责任调用delete-但只能在其中一个指针上调用delete。容器中包含的指针将被析构函数,这是您提供的引号所指示的。指针指向的对象不会自动销毁。您必须在指针上准确地调用deleted一次。更简单的方法是使用某种智能指针为您管理它。
std::list< Bullet*>::iterator bullet_it;

    for( bullet_it = (a_pCell->m_BulletPList).begin(); bullet_it != (a_pCell->m_BulletPList).end(); bullet_it++) {

        bool l_Bullet_trash = false;
        Bullet* bullet1 = *bullet_it;

        // conditions would set this to true

        if ( l_Bullet_Trash )
            // TrashBullet( bullet1 );
            continue;
        }
void CollisionMgr::TrashBullet(Bullet* a_pBullet, Cell* a_pCell)
{

    a_pBullet->Owner()->TrashBullet( a_pBullet );
    m_BulletPList.remove( a_pBullet );
    //a_pCell->m_BulletPList.remove( a_pBullet );

    delete a_pBullet;
}