我花了几个小时才找到这个bug,现在至少我知道问题在哪里,但我不知道为什么。
所以我有:
std::vector< std::vector <Organism* > >world;
我有基类Organism
和子类Beetle
和Ant
。
在基类Organism
中我有虚函数:
private:
bool energy;
public:
Organism():energy(true){}
virtual void removeEnergy(){
energy = false;
}
virtual bool hasEnergy(){
return energy;
}
virtual void resetEnergy(){
energy = true;
}
我没有在任何子课上覆盖它们。我在子类中调用了基类构造函数。
当我调用此函数时:
void World::replaceOrganism(int x, int y, int newX, int newY){
world[newX][newY] = world[x][y];
world[x][y] = new Organism;
world[newX][newY]->removeEnergy(); // this line
}
它仅从此类对象中移除能量。这意味着如果向量world
中有多个甲壳虫,则按此行:
world[newX][newY]->removeEnergy();
从所有这些中移除能量。
我认为它与矢量有关。有人有什么建议吗?如果您需要更多信息 - &gt;评论我会补充。
如果删除该行,还有一件事:
world[newX][newY]->removeEnergy();
然后Organism
类对象或其子对象的能量不会改变。
EDITED
创建世界载体:
world.resize(worldSizeX);
for (int x = 0; x < worldSizeX; x++){
world[x] = std::vector< Organism* >(worldSizeY);
// INITATES world ARRAY
for (int y = 0; y < worldSizeY; y++){
world[x][y] = new Organism;
}
// !INITATES world ARRAY
}
EDITED
用这个改变replaceOrganism功能:
void World::replaceOrganism(int x, int y, int newX, int newY){
delete world[newX][newY];
world[newX][newY] = world[x][y];
delete world[x][y];
world[x][y] = new Organism;
}
删除单词[newX] [newY]指向的所有类对象,但只调用一次函数。
EDITED
将Organism
类对象替换为其子对象的函数。
bool World::createOrganism(int x, int y, Organism* organism){
Organism* empty = new Organism;
if (world[x][y]->type() != empty->type()){
delete empty;
return false;
}
else{
delete empty;
world[x][y] = organism;
return true;
}
}
我叫它:
createOrganism(2,3,new Beetle);
EDITED
void World::generateOrganisms(Organism* organism, int amount){
while (amount != 0){
int x = rand() % worldSizeX;
int y = rand() % worldSizeY;
if (createOrganism(x, y, organism)){
amount--;
}
}
}
一切都指向同一个物体。
答案 0 :(得分:3)
在generateOrganisms(Organism* organism, int amount)
中,您设置的所有指针都指向同一个生物体。所以甲壳虫都一样。
您需要为您的生物预测额外的虚拟功能:
Organism *clone() {
// create a new organism of the same type
}
应为每个孩子覆盖此虚函数,以使用正确的构造函数创建新的有机体。
然后您可以更新您的创建功能:
bool World::createOrganism(int x, int y, Organism* organism){
Organism* empty = new Organism;
if (world[x][y]->type() != empty->type()){
delete empty;
return false;
}
else{
delete empty;
world[x][y] = organism->clone(); // use a clone, not the original
return true;
}
}
此外,我不确定是否会根据需要删除所有未使用的对象(至少很难说只提供您提供的snipets)。值得研究shared_ptr的潜在用途,以避免泄漏内存。