列表与抽象矢量 类

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更类似于链表。每个元素可能使用更多的内存,但对于随机插入和删除来说肯定更好。但是 listvector 的用法并不是问题的根源。

至于你的编译错误。可能是因为:

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