我有一个我不明白的阻塞问题。一般来说,我正在制作一种蚁丘模拟。内部有一个主要通道,分为几段,蚂蚁可以从其中一些段进入房间。所有这三个类(通道、段、腔室)都有一个共同点——当前访问它们的蚂蚁的集合。所以有一个抽象类AntHolder
,其中包含vector<Ant*>
(仅显示与案例相关的成员):
class AntHolder
{
protected:
std::vector<Ant*> ants;
/* some other members here */
public:
virtual bool antEnter(Ant* ant) = 0;
/* some other functions here */
};
该antEnter
函数在派生类中的实现方式不同,但通常用于将 ant 添加到ants
. 从派生类中,我对类特别感兴趣AntChamber
(这里也省略了不太重要的成员):
class AntChamber : public AntHolder
{
protected:
int itemCapacity;
int additionalCapacity;
std::vector<Item*> items;
bool hasFood;
bool hasEgg;
public:
bool putItem(Item* item);
virtual bool antEnter(Ant* ant);
};
该putItem
函数与函数类似antEnter
,但它将Item
对象添加到items
集合中。(物品例如食物,由蚂蚁从一个房间移动到另一个房间。)下面显示了这两个功能的实现:
bool AntChamber::antEnter(Ant* ant)
{
if (items.size() + ants.size() == itemCapacity + additionalCapacity) return false;
ants.push_back(ant);
return true;
}
bool AntChamber::putItem(Item* item)
{
if (items.size() == itemCapacity ||
items.size() + ants.size() == itemCapacity + additionalCapacity)
return false;
if (item->getItemKind() == Food) hasFood = true; // Food == enum value
else if (item->getItemKind() == Egg) hasEgg = true; // Egg == enum value
items.push_back(item);
return true;
}
您可以清楚地看到,它们几乎相同。但是当谈到它们的效果时,有一个关键的、令人惊讶的差异,这就是我的问题的核心。
假设我已经AntChamber* chamber
构建了一个。当我运行以下代码时:
Item* item = new Item(Food);
chamber->putItem(item);
, 然后之后两者item
和chamber->items.back()
指向这个对象的一些内存。但是当我运行类似的代码时:
Ant* ant = new Ant(chamber);
chamber->antEnter(ant));
,然后ant
指向对象,但chamber->ants.back()
指向NULL!
我绝对无法理解发生了什么,尤其是两者putItem
实际上antEnter
都在做同样的事情:push_back
指针,它是通过参数传递的。我已经尝试用一些更简单的代码来模拟这种情况,比如:
class A { };
class B { };
class C
{
vector<A*> va;
vector<B*> vb;
public:
A* vaBack() { return va.back(); }
B* vbBack() { return vb.back(); }
void addA(A* a) { va.push_back(a); }
void addB(B* b) { vb.push_back(b); }
};
int main(int argc, char** argv)
{
A* a = new A();
B* b = new B();
C* c = new C();
cout << (unsigned int)a << endl;
c->addA(a);
cout << (unsigned int)c->vaBack() << endl;
cout << (unsigned int)b << endl;
c->addB(b);
cout << (unsigned int)c->vbBack() << endl;
delete c;
delete b;
delete a;
}
,但它似乎工作得很好 - 没有一个指针是 0x000000。