无法从向量中删除元素,试图引用已删除的函数

Can't delete element from vector, attempting to reference deleted function

我正在使用 SFML 库在 C++ 中制作 "version" of Space Invaders,但是当我尝试删除入侵者时遇到问题。 我的代码中有这个错误:

Enemy &Enemy::operator =(const Enemy &)': attempting to reference a deleted function

我尝试查看此论坛中推荐的其他解决方案,但我要么不理解它们,要么情况不同。

EnemyControler.cpp

EnemyControler::EnemyControler()
{
    Enemy::Type types[] = {
        Enemy::Type::Squid, Enemy::Type::Crab, Enemy::Type::Crab,
        Enemy::Type::Octopus, Enemy::Type::Octopus
    };


    for (int y = 0; y < 5; y++) { // Add enemies to the vector
        for (int x = 0; x < 11; x++){
            float enemyX = x * 40 + (gapBetweenEnemies * x * 3) + Enemy::enemyWidth; // Make horizontal gap between them
            float enemyY = y * 40 + (gapBetweenEnemies * y) + Enemy::enemyHeight; // Make vertical gap between them
            enemies.emplace_back(sf::Vector2f{ enemyX, enemyY }, types[y]); // Add them to the vector
        }
    }
}
void EnemyControler::destroyEnemy()
{
    for (auto iterator = begin(enemies); iterator != end(enemies);) {
        auto& enemy = *iterator;
        if (enemy.isAlive()) {
            iterator++;
        }
        else {
            iterator = enemies.erase(iterator);
        }
    }
}

问题出在 destroyEnemy 函数中。具体在 iterator = enemies.erase(iterator);

EnemyControler.h

class EnemyControler
{
public:
    EnemyControler();

    void destroyEnemy();
private:
    const int gapBetweenEnemies = 10;

    std::vector<Enemy> enemies;
};

Enemy.cpp

Enemy::Enemy(sf::Vector2f startingPosition, Type type) : 
Collidable(enemyWidth, enemyHeight), newPosition(startingPosition), enemyType(type), startingPosition(startingPosition)
{
}

Enemy.h

class Enemy : public Collidable
{
public:
    enum class Type // enum for different looking enemies
    {
        Crab, Octopus, Squid
    };
    Enemy(sf::Vector2f startingPosition, Type type);

    constexpr static float enemyWidth = 30.0f;
    constexpr static float enemyHeight = 30.0f;

private:
    sf::Vector2f newPosition;
    Type enemyType;

    const sf::Vector2f startingPosition;
};

Collidable.cpp

Collidable::Collidable(float width, float height) :
 spriteSize(width, height)
{
}

Collidable.h

class Collidable
{
public:
    Collidable(float width, float height);
private:
    sf::Vector2f spriteSize;
};

如果没有解决这个问题的简单方法,或者这个问题只能通过重写所有代码来解决,也许你可以建议另一种从向量中删除 invader 的方法。

如果 class 有一个 const 成员变量,那么 class operator= 的复制赋值运算符将被编译器默认删除。

来自 https://en.cppreference.com/w/cpp/language/copy_assignment :

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:
- T has a non-static data member of non-class type (or array thereof) that is const;

这是因为编译器无法猜测将对象 A 复制到对象 B 意味着什么,如果它们的 class 的对象包含一个 const成员变量。编译器应该忽略那个特定的成员变量吗?编译器是否应该猜测你的意思是 const,除了复制分配时,那么就这一次没关系——我会换个角度看?编译器不知道你喜欢什么,所以它只是删除它。

一个选项是为您的 class.

显式定义复制赋值运算符

但是,startingPosition 已经声明为私有,因此 class 之外的任何东西都不太可能无意中更改它。我建议只删除 const 说明符。

为什么复制赋值运算符很重要?我正在尝试删除内容,而不是复制分配它们

当一个元素从vector中删除时,vector"above"中的所有元素都需要被删除的元素向下移动以填补空白。这是通过复制赋值运算符发生的。

来自 https://en.cppreference.com/w/cpp/container/vector/erase :

Complexity
Linear: the number of calls to the destructor of T is the same as the number of elements erased, the assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements