离开成功使用std :: erase的方法后,删除了错误的元素

时间:2017-08-13 14:36:06

标签: c++ vector erase remove-if

我正在研究图形引擎。引擎有std::vector个drawable。 Drawable是一个包含Model和DrawableObject的对象,它又包含着色器程序和来自2D或3D模型的束顶点。添加新的Drawables很顺利,当我尝试删除Drawable时会出现问题。最后一个Drawable将被删除,倒数第二个将更改其值。

代码

Drawable.h

class Drawable
{
public:
    Drawable& operator=(const Drawable& other)
    { 
        Drawable tmp(other);
        std::swap(model, other.model);
        std::swap(drawableObject, other.drawableObject);
        return *this;
    }

    Drawable(domain::Model& model, DrawableObject& drawableObject) :
        model(model),
        drawableObject(drawableObject)
    {}

    domain::Model& model;
    DrawableObject& drawableObject;
};

game.cpp

void Game::init_game()
{
    human = domain::Model(glm::vec3(0, 0, -3));
    moveables.push_back(&human);
    room = domain::Model(glm::vec3(0, 0, -10));
    props.push_back(&room);
    cube = domain::Model(glm::vec3(0, 0, 0));
    props.push_back(&cube);
}

void Game::init_graphics_engine()
{
    // ... load graphics models

    // add drawables
    graphicsEngine->add(cube, Drawable::CUBE);
    graphicsEngine->add(human, Drawable::HUMAN);
    graphicsEngine->add(room, Drawable::ROOM);
    graphicsEngine->add(topDownScene->cursor, Drawable::MARKER);
}

graphics_engine / engine.cpp

void Engine::add(domain::Model& model, unsigned int object)
{
    auto drawableObject = drawableObjects[object];
    // make sure not to add a model that already is represented
    auto it = std::find_if(drawables.begin(), drawables.end(), [&model](Drawable& drawable) {return &drawable.model == &model;});
    if(drawableObject && it == drawables.end())
        drawables.push_back(Drawable(model, *drawableObject));
}

void Engine::remove(domain::Model& model)
{
    auto predicate = [&model](Drawable& drawable) 
    {
        return &drawable.model == &model;
    };
    drawables.erase(std::remove_if(drawables.begin(), drawables.end(), predicate), drawables.end());
}

场景

这是我启动应用程序时的场景:

scene on startup

在尝试擦除小人物后,这就是场景的样子。中间的立方体:

enter image description here

代码删除了最后一个Drawable,它是白色标记,而不是“人类”。立方体,并改变了房间的z位置。这几乎总是发生,它删除了最后一个元素并将秒的z更改为最后一个。只有当我添加“人类”时,它才有效。立方体最后在init方法中。

断点

删除对象之前:

enter image description here

删除对象后:

enter image description here

这是正确的。

离开remove方法并查看渲染循环:

enter image description here

不知何故改变了。

1 个答案:

答案 0 :(得分:0)

我将类成员更改为指针。现在它有效。评论是对的,我没有对tmp变量做任何事情。

class Drawable
{
public:
    Drawable& operator=(const Drawable& other)
    { 
        this->model = other.model;
        this->drawableObject = other.drawableObject;
        return *this;
    }

    Drawable(domain::Model* model, std::shared_ptr<DrawableObject> drawableObject) :
        model(model),
        drawableObject(drawableObject)
    {}

    domain::Model* model;
    std::shared_ptr<DrawableObject> drawableObject;
};