C++ 删除其引用在三个不同列表中维护的指针对象
我不知道如何解决这个问题: “Player”类维护Bullet*对象的列表: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支持这一点)。您有一个拥有强引用的“权威”容器,因此
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;
}