开发者

Remove pointer object whose reference is maintained in three different lists

开发者 https://www.devze.com 2022-12-28 02:29 出处:网络
I am not sure how to approach this problem: \'Player\' class maintains a list of Bullet* objects: class Player

I am not sure how to approach this problem:

'Player' class maintains a list of Bullet* objects:

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

When the player fires a Bullet, it is added to this list. Also, inside the constructor of bullet, a reference of the same object is updated in CollisionMgr, where CollisionMgr also mantains a list of Bullet*.

Bullet::Bullet(GameGL*a_pGameGL, Player*a_pPlayer)
: GameObject( a_pGameGL )
{      
    m_pPlayer = a_pPlayer;

    m_pGameGL->GetCollisionMgr()->AddBullet(this);
}

class CollisionMgr
{

void AddBullet(Bullet* 开发者_运维知识库a_pBullet);

protected:
std::list< Bullet*> m_BulletPList;
}

In CollisionMgr.Update(); based on some conditions, I populate class Cell which again contain a list of Bullet*. Finally, certain conditions qualify a Bullet to be deleted. Now, these conditions are tested upon while iterating through a Cell's list. So, if I have to delete the Bullet object, from all these places, how should I do it so that there are no more dangling references to it?

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;
        }

Also, I was reading about list::remove, and it mentions that it calls the destructor of the object we are trying to delete. Given this info, if I delete from one list, the object does not exist, but the list would still contain a reference to it..How do I handle all these problems?


One option is to use reference counting with weak references (Boost supports this). You have one "authoritative" container that owns the strong reference, and hence deletes any Bullet removed from it. All other containers use weak references, and remove Bullets when they find that the weak reference has become invalid.

This does complicate things slightly in several places, but it is logically much cleaner and safer than other mechanisms.


You are not storing bullets in these lists, but pointers to bullets, so no destructor will be called. The objects can be safely removed from all lists, but you will need to call delete yourself.


Interesting observation or maybe this is just a part of the 'undefined behavior'. So, this is how I am trashing a bullet and its not giving me an error..as of now:

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;
}

So, Once I "remove" references to Bullet from lists, I then manually delete it. What confuses me is, from the description of 'list::remove' :

void remove ( const T& value ); Remove elements with specific value. Removes from the list all the elements with a specific value. This calls the destructor of these objects and reduces the list size by the amount of elements removed.

Thus, when I call the remove on bullet from the list, the destructor for that bullet object should be called. But, that aint happening here... So, is this just a part of the undefined behavior and my compiler's quirk or am I missing something trivial here ?

0

精彩评论

暂无评论...
验证码 换一张
取 消