列表与抽象矢量 类
List vs Vector with Abstract Classes
警告:来自没有经验的人的问题:)
嗨,
我正在制作 mock-up 个 space 入侵者作为家庭作业,我正在研究飞船和外星人将要使用的子弹 fire/drop。我有一个抽象基础 class 来处理所有子弹,有两个派生 classes -- 导弹和炸弹。
我最初使用向量,但我在某处读到列表会更有效,因为它们可以如此快速地添加和删除(?)。
但是,我是列表的新手,我遇到了一些麻烦。老实说,我完全不确定如何或是否可以使用带有抽象 class 的列表。
我还没有实现炸弹 class 因为我想让导弹 class 先工作。
这里以基地class(射击)+导弹的header为例:
enum attackType { BOMB, MISSILE };
class shot
{
private:
float xPos,
yPos;
attackType bombOrMissile;
public:
shot(Vector2f pos, attackType b_OR_m); // passed ship pos + who fired shot
virtual void draw(RenderWindow & win) = 0; // draws bullet on screen
virtual Sprite & getSprite() = 0; // gives sprite information
};
class missile : public shot
{
private:
Sprite missileSprite;
public:
missile(Vector2f pos, Texture & t);
void draw(RenderWindow & win);
Sprite & getSprite();
};
我有一个 "Shot manager" class 控制项目符号列表。它 increments/decrements 列表并更改精灵位置。
Header :
class shotMgr
{
private:
list<shot*> shotsFired;
Texture missileTexture;
public:
shotMgr(); // loads texture
void shoot(attackType b_OR_m, Vector2f pos);
void disappear();
void move();
void draw(RenderWindow& win);
int getAmountFilled() { return shotsFired.size(); }
};
我的主要问题是:如何处理这里的语法?试图绕过 ptrs,我让自己感到困惑。在这种情况下,向量最终会成为更好的选择,还是我做错了什么?
这是我的 shotMgr 函数之一,用于演示我当前正在做的事情(它无法编译);其他功能在句法上相似:
void shotMgr::disappear()
{
list<shot>::iterator iter;
for (iter = shotsFired.begin(); iter != shotsFired.end();)
{
if (iter->getSprite().getPosition().y < 0)
{
iter = shotsFired.erase(iter);
}
else
iter++;
}
}
如有任何建议,我们将不胜感激。谢谢!
std::vector
在集合末尾添加和删除时效率最高。当代码从向量中的其他任何位置插入或删除时,索引大于被访问元素的所有元素都会产生 "move"。也就是说,当您插入时,数组中该元素右侧的所有内容都需要 "move over by one"。同样,当您移除时,被移除元素右侧的所有内容都需要滑到左侧。与使用普通数组作为集合没有什么不同。
std::list
更类似于链表。每个元素可能使用更多的内存,但对于随机插入和删除来说肯定更好。但是 list
与 vector
的用法并不是问题的根源。
至于你的编译错误。可能是因为:
list<shot>::iterator iter;
您正在为 list<shot>::iterator
声明一个迭代器,但您的集合是 list<shot*>
类型。所以你可能想要 list<shot*>::iterator
。让我们修复你的功能。 auto
来拯救你,这样你就不用费心去想这些东西了。
void shotMgr::disappear()
{
for (auto iter = shotsFired.begin(); iter != shotsFired.end();)
{
shot* ptrShot = *iter;
if (ptrShot->getSprite().getPosition().y < 0)
{
iter = shotsFired.erase(iter);
}
else
{
iter++;
}
}
}
警告:来自没有经验的人的问题:)
嗨,
我正在制作 mock-up 个 space 入侵者作为家庭作业,我正在研究飞船和外星人将要使用的子弹 fire/drop。我有一个抽象基础 class 来处理所有子弹,有两个派生 classes -- 导弹和炸弹。
我最初使用向量,但我在某处读到列表会更有效,因为它们可以如此快速地添加和删除(?)。 但是,我是列表的新手,我遇到了一些麻烦。老实说,我完全不确定如何或是否可以使用带有抽象 class 的列表。
我还没有实现炸弹 class 因为我想让导弹 class 先工作。
这里以基地class(射击)+导弹的header为例:
enum attackType { BOMB, MISSILE };
class shot
{
private:
float xPos,
yPos;
attackType bombOrMissile;
public:
shot(Vector2f pos, attackType b_OR_m); // passed ship pos + who fired shot
virtual void draw(RenderWindow & win) = 0; // draws bullet on screen
virtual Sprite & getSprite() = 0; // gives sprite information
};
class missile : public shot
{
private:
Sprite missileSprite;
public:
missile(Vector2f pos, Texture & t);
void draw(RenderWindow & win);
Sprite & getSprite();
};
我有一个 "Shot manager" class 控制项目符号列表。它 increments/decrements 列表并更改精灵位置。
Header :
class shotMgr
{
private:
list<shot*> shotsFired;
Texture missileTexture;
public:
shotMgr(); // loads texture
void shoot(attackType b_OR_m, Vector2f pos);
void disappear();
void move();
void draw(RenderWindow& win);
int getAmountFilled() { return shotsFired.size(); }
};
我的主要问题是:如何处理这里的语法?试图绕过 ptrs,我让自己感到困惑。在这种情况下,向量最终会成为更好的选择,还是我做错了什么?
这是我的 shotMgr 函数之一,用于演示我当前正在做的事情(它无法编译);其他功能在句法上相似:
void shotMgr::disappear()
{
list<shot>::iterator iter;
for (iter = shotsFired.begin(); iter != shotsFired.end();)
{
if (iter->getSprite().getPosition().y < 0)
{
iter = shotsFired.erase(iter);
}
else
iter++;
}
}
如有任何建议,我们将不胜感激。谢谢!
std::vector
在集合末尾添加和删除时效率最高。当代码从向量中的其他任何位置插入或删除时,索引大于被访问元素的所有元素都会产生 "move"。也就是说,当您插入时,数组中该元素右侧的所有内容都需要 "move over by one"。同样,当您移除时,被移除元素右侧的所有内容都需要滑到左侧。与使用普通数组作为集合没有什么不同。
std::list
更类似于链表。每个元素可能使用更多的内存,但对于随机插入和删除来说肯定更好。但是 list
与 vector
的用法并不是问题的根源。
至于你的编译错误。可能是因为:
list<shot>::iterator iter;
您正在为 list<shot>::iterator
声明一个迭代器,但您的集合是 list<shot*>
类型。所以你可能想要 list<shot*>::iterator
。让我们修复你的功能。 auto
来拯救你,这样你就不用费心去想这些东西了。
void shotMgr::disappear()
{
for (auto iter = shotsFired.begin(); iter != shotsFired.end();)
{
shot* ptrShot = *iter;
if (ptrShot->getSprite().getPosition().y < 0)
{
iter = shotsFired.erase(iter);
}
else
{
iter++;
}
}
}